diff options
Diffstat (limited to 'src/List.gleam')
-rw-r--r-- | src/List.gleam | 145 |
1 files changed, 94 insertions, 51 deletions
diff --git a/src/List.gleam b/src/List.gleam index 4505a74..1ca291b 100644 --- a/src/List.gleam +++ b/src/List.gleam @@ -8,158 +8,201 @@ import Maybe exposing Maybe(..) // external length : |List(a)| -> Int = :erlang.length -test length = +test length { length([]) |> Assert.equal(_, 0) length([1]) |> Assert.equal(_, 1) length([1, 1]) |> Assert.equal(_, 2) length([1, 1, 1]) |> Assert.equal(_, 3) +} // Using the Erlang C BIF implementation. // external reverse : |List(a)| -> List(a) = :erlang.reverse -test reverse = +test reverse { length([]) |> Assert.equal(_, []) length([1, 2, 3, 4, 5]) |> Assert.equal(_, [5, 4, 3, 2, 1]) +} -fn is_empty(list) = +fn is_empty(list) { list == [] +} -test is_empty = +test is_empty { is_empty([]) |> Assert.true is_empty([1]) |> Assert.false +} -fn member(list, elem) = - case list +fn member(list, elem) { + case list { | [] => False | elem :: _ => True | _ :: rest => member(rest, elem) + } +} -test is_member = +test is_member { is_member([0, 4, 5, 1], 1) |> Assert.true is_member([0, 4, 5, 7], 1) |> Assert.false is_member([], 1) |> Assert.false +} -fn head(list) = - case list +fn head(list) { + case list { | [] => Nothing | elem :: _ => Just(elem) + } +} -test head = +test head { head([0, 4, 5, 7]) |> Assert.equal(_, Just(0)) head([]) |> Assert.equal(_, Nothing) +} -fn tail(list) = - case list +fn tail(list) { + case list { | [] => Nothing | _ :: rest => Just(rest) + } +} -test tail = +test tail { tail([0, 4, 5, 7]) |> Assert.equal(_, Just([4, 5, 7])) tail([0]) |> Assert.equal(_, Just([])) tail([]) |> Assert.equal(_, Nothing) +} -fn filter(list, fun) = +fn filter(list, fun) { filter(list, fun, []) +} -test filter = +test filter { filter([], |x| True) |> Assert.equal(_, []) filter([0, 4, 5, 7, 3], |x| True) |> Assert.equal(_, [0, 4, 5, 7, 3]) filter([0, 4, 5, 7, 3], |x| x > 4) |> Assert.equal(_, [5, 7]) filter([0, 4, 5, 7, 3], |x| x < 4) |> Assert.equal(_, [0, 3]) +} -fn filter(list, fun, acc) = - case list +fn filter(list, fun, acc) { + case list { | [] => reverse(acc) - | x :: xs => ( - new_acc = case fun(x) + | x :: xs => + new_acc = + case fun(x) { | True => x :: acc | False => acc + } filter(xs, fun, new_acc) - ) + } +} -fn map(list, fun) = +fn map(list, fun) { map(list, fun, []) +} -test map = +test map { map([], |x| * 2) |> Assert.equal(_, []) map([0, 4, 5, 7, 3], |x| x * 2) |> Assert.equal(_, [0, 8, 10, 14, 6]) +} -fn map(list, fun, acc) = - case list +fn map(list, fun, acc) { + case list { | [] => reverse(acc) | x :: xs => map(xs, fun, fun(x) :: acc) + } +} -fn drop(list, n) = - case n <= 0 +fn drop(list, n) { + case n <= 0 { | True => list - | False => ( - case list + | False => + case list { | [] => [] | _ :: xs => drop(xs, n - 1) - ) + } + } +} -test drop/2 = +test drop/2 { drop([], 5) |> Assert.equal(_, []) drop([1, 2, 3, 4, 5, 6, 7, 8], 5) |> Assert.equal(_, [6, 7, 8]) +} -fn take(list, n) = +fn take(list, n) { take(list, n, []) +} -fn take(list, n, acc) = - case n <= 0 +fn take(list, n, acc) { + case n <= 0 { | True => reverse(acc) - | False => ( - case list + | False => + case list { | [] => reverse(acc) | x :: xs => take(xs, n - 1, x :: acc) - ) + } + } +} -test take = +test take { take([], 5) |> Assert.equal(_, []) take([1, 2, 3, 4, 5, 6, 7, 8], 5) |> Assert.equal(_, [1, 2, 3, 4, 5]) +} -fn of(x) = +fn of(x) { [x] +} -test of() = +test of() { of([]) |> Assert.equal(_, [[]]) of(1) |> Assert.equal(_, [1]) +} -fn new() = +fn new() { [] +} -test new() = +test new() { new() |> Assert.equal(_, []) +} -fn flatten(lists) = +fn flatten(lists) { flatten(lists, []) +} -test flatten() = +test flatten() { flatten([]) |> Assert.equal(_, []) flatten([[]]) |> Assert.equal(_, []) flatten([[], [], []]) |> Assert.equal(_, []) flatten([[1, 2], [], [3, 4]]) |> Assert.equal(_, [1, 2, 3, 4]) +} -fn flatten(lists, acc) = - case lists +fn flatten(lists, acc) { + case lists { | [] => acc | l :: rest => flatten(rest, acc ++ l) + } +} -fn foldl(list, acc, fun) = - case list +fn foldl(list, acc, fun) { + case list { | [] => acc | x :: rest => foldl(rest, fun(x, acc), fun) + } +} -test foldl() = +test foldl() { foldl([1, 2, 3], [], |x, acc| x :: acc) |> Assert.equal(_, [3, 2, 1]) +} -fn foldr(list, acc, fun) = - case list +fn foldr(list, acc, fun) { + case list { | [] => acc | x :: rest => fun(x, foldl(rest, acc, fun)) + } +} -test foldr() = +test foldr() { foldr([1, 2, 3], [], |x, acc| x :: acc) |> Assert.equal(_, [1, 2, 3]) +} |