diff options
-rw-r--r-- | gen/list.erl | 74 | ||||
-rw-r--r-- | src/list.gleam | 156 |
2 files changed, 151 insertions, 79 deletions
diff --git a/gen/list.erl b/gen/list.erl index 662b283..cf76f31 100644 --- a/gen/list.erl +++ b/gen/list.erl @@ -2,7 +2,7 @@ -compile(no_auto_import). -include_lib("eunit/include/eunit.hrl"). --export([length/1, reverse/1, is_empty/1, has_member/2, head/1, tail/1, map/2, do_traverse/3, traverse/2, new/0, append/2, flatten/1, foldl/3, foldr/3]). +-export([length/1, reverse/1, is_empty/1, has_member/2, head/1, tail/1, filter/2, map/2, do_traverse/3, traverse/2, drop/2, take/2, new/0, append/2, flatten/1, foldl/3, foldr/3]). length(A) -> erlang:length(A). @@ -80,6 +80,33 @@ tail_test() -> expect:equal(tail([]), {error, empty}). -endif. +do_filter(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + NewAcc = case Fun(X) of + true -> + [X | Acc]; + + false -> + Acc + end, + do_filter(Xs, Fun, NewAcc) + end. + +filter(List, Fun) -> + do_filter(List, Fun, []). + +-ifdef(TEST). +filter_test() -> + expect:equal(filter([], fun(X) -> true end), []), + expect:equal(filter([0, 4, 5, 7, 3], fun(X) -> true end), [0, 4, 5, 7, 3]), + expect:equal(filter([0, 4, 5, 7, 3], fun(X) -> X > 4 end), [5, 7]), + expect:equal(filter([0, 4, 5, 7, 3], fun(X) -> X < 4 end), [0, 3]). +-endif. + do_map(List, Fun, Acc) -> case List of [] -> @@ -129,6 +156,51 @@ traverse_test() -> expect:equal(traverse([4, 6, 5, 7, 3], Fun), {error, 7}). -endif. +drop(List, N) -> + case N =< 0 of + true -> + List; + + false -> + case List of + [] -> + []; + + [X | Xs] -> + drop(Xs, N - 1) + end + end. + +-ifdef(TEST). +drop_test() -> + expect:equal(drop([], 5), []), + expect:equal(drop([1, 2, 3, 4, 5, 6, 7, 8], 5), [6, 7, 8]). +-endif. + +do_take(List, N, Acc) -> + case N =< 0 of + true -> + reverse(Acc); + + false -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_take(Xs, N - 1, [X | Acc]) + end + end. + +take(List, N) -> + do_take(List, N, []). + +-ifdef(TEST). +take_test() -> + expect:equal(take([], 5), []), + expect:equal(take([1, 2, 3, 4, 5, 6, 7, 8], 5), [1, 2, 3, 4, 5]). +-endif. + new() -> []. diff --git a/src/list.gleam b/src/list.gleam index 3f79b52..e0a8f42 100644 --- a/src/list.gleam +++ b/src/list.gleam @@ -78,40 +78,40 @@ test tail { |> expect:equal(_, Error(Empty)) } -// fn do_filter(list, fun, acc) { -// case list { -// | [] -> reverse(acc) -// | [x | xs] -> -// let new_acc = -// case fun(x) { -// | True -> [x | acc] -// | False -> acc -// } -// do_filter(xs, fun, new_acc) -// } -// } - -// pub fn filter(list, fun) { -// do_filter(list, fun, []) -// } - -// test filter { -// [] -// |> filter(_, fn(x) { True }) -// |> expect:equal(_, []) - -// [0, 4, 5, 7, 3] -// |> filter(_, fn(x) { True }) -// |> expect:equal(_, [0, 4, 5, 7, 3]) - -// [0, 4, 5, 7, 3] -// |> filter(_, fn(x) { x > 4 }) -// |> expect:equal(_, [5, 7]) - -// [0, 4, 5, 7, 3] -// |> filter(_, fn(x) { x < 4 }) -// |> expect:equal(_, [0, 3]) -// } +fn do_filter(list, fun, acc) { + case list { + | [] -> reverse(acc) + | [x | xs] -> + let new_acc = + case fun(x) { + | True -> [x | acc] + | False -> acc + } + do_filter(xs, fun, new_acc) + } +} + +pub fn filter(list, fun) { + do_filter(list, fun, []) +} + +test filter { + [] + |> filter(_, fn(x) { True }) + |> expect:equal(_, []) + + [0, 4, 5, 7, 3] + |> filter(_, fn(x) { True }) + |> expect:equal(_, [0, 4, 5, 7, 3]) + + [0, 4, 5, 7, 3] + |> filter(_, fn(x) { x > 4 }) + |> expect:equal(_, [5, 7]) + + [0, 4, 5, 7, 3] + |> filter(_, fn(x) { x < 4 }) + |> expect:equal(_, [0, 3]) +} fn do_map(list, fun, acc) { case list { @@ -167,50 +167,50 @@ test traverse { } -// pub fn drop(list, n) { -// case n <= 0 { -// | True -> list -// | False -> -// case list { -// | [] -> [] -// | [x | xs] -> drop(xs, n - 1) -// } -// } -// } - -// test drop { -// [] -// |> drop(_, 5) -// |> expect:equal(_, []) - -// [1, 2, 3, 4, 5, 6, 7, 8] -// |> drop(_, 5) -// |> expect:equal(_, [6, 7, 8]) -// } - -// fn do_take(list, n, acc) { -// case n <= 0 { -// | True -> reverse(acc) -// | False -> -// case list { -// | [] -> reverse(acc) -// | [x | xs] -> take(xs, n - 1, [x | acc]) -// } -// } -// } - -// pub fn take(list, n) { -// do_take(list, n, []) -// } - -// test take { -// [] -// |> take(_, 5) -// |> expect:equal(_, []) -// [1, 2, 3, 4, 5, 6, 7, 8] -// |> take(_, 5) -// |> expect:equal(_, [1, 2, 3, 4, 5]) -// } +pub fn drop(list, n) { + case n <= 0 { + | True -> list + | False -> + case list { + | [] -> [] + | [x | xs] -> drop(xs, n - 1) + } + } +} + +test drop { + [] + |> drop(_, 5) + |> expect:equal(_, []) + + [1, 2, 3, 4, 5, 6, 7, 8] + |> drop(_, 5) + |> expect:equal(_, [6, 7, 8]) +} + +fn do_take(list, n, acc) { + case n <= 0 { + | True -> reverse(acc) + | False -> + case list { + | [] -> reverse(acc) + | [x | xs] -> do_take(xs, n - 1, [x | acc]) + } + } +} + +pub fn take(list, n) { + do_take(list, n, []) +} + +test take { + [] + |> take(_, 5) + |> expect:equal(_, []) + [1, 2, 3, 4, 5, 6, 7, 8] + |> take(_, 5) + |> expect:equal(_, [1, 2, 3, 4, 5]) +} pub fn new() { [] |