From 2cbe6bd721ae2be68c29e4de71db51bafc3478f8 Mon Sep 17 00:00:00 2001 From: Louis Pilfold Date: Mon, 18 Mar 2019 01:12:09 +0000 Subject: tuple module, decode lists --- gen/any.erl | 60 +++++++++++---- gen/tuple.erl | 23 ++++++ src/any.gleam | 201 +++++++++++++++++++++++++++----------------------- src/gleam__stdlib.erl | 5 +- src/tuple.gleam | 23 ++++++ 5 files changed, 205 insertions(+), 107 deletions(-) create mode 100644 gen/tuple.erl create mode 100644 src/tuple.gleam diff --git a/gen/any.erl b/gen/any.erl index 09d7d9d..aa59a22 100644 --- a/gen/any.erl +++ b/gen/any.erl @@ -4,6 +4,12 @@ -export([from/1, unsafeCoerce/1, string/1, int/1, float/1, bool/1, thunk/1, list/2, tuple/1, field/2]). +list_module() -> + list. + +tuple_module() -> + tuple. + from(A) -> gleam__stdlib:identity(A). @@ -55,17 +61,40 @@ bool_test() -> -endif. thunk(A) -> - gleam__stdlib:thunk(A). + gleam__stdlib:decode_thunk(A). + +-ifdef(TEST). +thunk_test() -> + expect:is_ok(thunk(from(fun() -> 1 end))), + expect:equal(result:map(thunk(from(fun() -> 1 end)), fun(F) -> F() end), + {ok, from(1)}), + expect:is_error(thunk(from(fun(X) -> X end))), + expect:is_error(thunk(from(1))), + expect:is_error(thunk(from([]))). +-endif. list_any(A) -> gleam__stdlib:decode_list(A). -list_module() -> - list. - list(Any, Decode) -> result:then(list_any(Any), - fun(X) -> (list_module()):traverse(X, Decode) end). + fun(Capture1) -> + (list_module()):traverse(Capture1, Decode) + end). + +-ifdef(TEST). +list_test() -> + expect:equal(list(from([]), fun string/1), {ok, []}), + expect:equal(list(from([]), fun int/1), {ok, []}), + expect:equal(list(from([1, 2, 3]), fun int/1), {ok, [1, 2, 3]}), + expect:equal(list(from([[1], [2], [3]]), + fun(Capture1) -> list(Capture1, fun int/1) end), + {ok, [[1], [2], [3]]}), + expect:is_error(list(from(1), fun string/1)), + expect:is_error(list(from(1.0), fun int/1)), + expect:is_error(list(from([<<"">>]), fun int/1)), + expect:is_error(list(from([from(1), from(<<"not an int">>)]), fun int/1)). +-endif. tuple(A) -> gleam__stdlib:decode_tuple(A). @@ -78,14 +107,19 @@ tuple_test() -> expect:is_error(tuple(from({1}))), expect:is_error(tuple(from({1, 2, 3}))), expect:equal(result:then(result:then(tuple(from({1, 2.0})), - fun(X) -> {A, B} = X, - result:map(int(A), - fun(I) -> - {I, B} - end) end), - fun(X) -> {A1, B1} = X, - result:map(float(B1), - fun(F) -> {A1, F} end) end), + fun(X) -> + result:map(int((tuple_module()):first(X)), + fun(F) -> + {F, + (tuple_module()):second(X)} + end) + end), + fun(X) -> + result:map(float((tuple_module()):second(X)), + fun(F) -> + {(tuple_module()):first(X), F} + end) + end), {ok, {1, 2.0}}). -endif. diff --git a/gen/tuple.erl b/gen/tuple.erl new file mode 100644 index 0000000..270bb29 --- /dev/null +++ b/gen/tuple.erl @@ -0,0 +1,23 @@ +-module(tuple). +-compile(no_auto_import). +-include_lib("eunit/include/eunit.hrl"). + +-export([first/1, second/1]). + +first(Tup) -> + {A, _} = Tup, + A. + +-ifdef(TEST). +first_test() -> + expect:equal(first({1, 2}), 1). +-endif. + +second(Tup) -> + {_, A} = Tup, + A. + +-ifdef(TEST). +second_test() -> + expect:equal(second({1, 2}), 2). +-endif. diff --git a/src/any.gleam b/src/any.gleam index 5deaeb8..262d39c 100644 --- a/src/any.gleam +++ b/src/any.gleam @@ -1,8 +1,17 @@ import list import atom +import tuple import result import expect +fn list_module() { + list +} + +fn tuple_module() { + tuple +} + // `Any` data is data that we don"t know the type of yet. // We likely get data like this from interop with Erlang, or from // IO with the outside world. @@ -95,32 +104,31 @@ test float { |> expect:equal(_, Error("Expected a Float, got `[]`")) } +// TODO // pub external fn atom(Any) -> Result(Atom, String) // = "gleam__stdlib" "decode_atom" -//// test atom { -//// // TODO -//// // make an atom here -//// // |> from -//// // |> atom -//// // |> expect:equal(_, Ok("")) - -//// // TODO -//// // make an atom here -//// // |> from -//// // |> atom -//// // |> expect:equal(_, Ok("ok")) - -//// let _ = 1 -//// |> from -//// |> atom -//// |> expect:is_error - -//// [] -//// |> from -//// |> atom -//// |> expect:is_error -//// } +// test atom { +// make an atom here +// |> from +// |> atom +// |> expect:equal(_, Ok("")) + +// make an atom here +// |> from +// |> atom +// |> expect:equal(_, Ok("ok")) + +// 1 +// |> from +// |> atom +// |> expect:is_error + +// [] +// |> from +// |> atom +// |> expect:is_error +// } pub external fn bool(Any) -> Result(Bool, String) = "gleam__stdlib" "decode_bool" @@ -148,83 +156,86 @@ test bool { } pub external fn thunk(Any) -> Result(fn() -> Any, String) - = "gleam__stdlib" "thunk" + = "gleam__stdlib" "decode_thunk" -//// test thunk { -//// let _ = fn() { 1 } -//// |> from -//// |> thunk -//// |> expect:is_ok - -//// let _ = fn(x) { x } -//// |> from -//// |> thunk -//// |> expect:is_error +test thunk { + fn() { 1 } + |> from + |> thunk + |> expect:is_ok -//// let _ = 1 -//// |> from -//// |> thunk -//// |> expect:is_error + fn() { 1 } + |> from + |> thunk + |> result:map(_, fn(f) { f() }) + |> expect:equal(_, Ok(from(1))) -//// [] -//// |> from -//// |> thunk -//// |> expect:is_error -//// } + fn(x) { x } + |> from + |> thunk + |> expect:is_error -external fn list_any(Any) -> Result(List(Any), String) = "gleam__stdlib" "decode_list" + 1 + |> from + |> thunk + |> expect:is_error -fn list_module() { - list + [] + |> from + |> thunk + |> expect:is_error } +external fn list_any(Any) -> Result(List(Any), String) = + "gleam__stdlib" "decode_list" + pub fn list(any, decode) { any - |> list_any - |> result:then(_, fn(x) { list_module():traverse(x, decode) }) + |> list_any + |> result:then(_, list_module():traverse(_, decode)) } -//// test list { -//// let _ = [] -//// |> from -//// |> list(string) -//// |> expect:equal(_, Ok([])) - -//// let _ = [] -//// |> from -//// |> list(atom) -//// |> expect:equal(_, Ok([])) - -//// let _ = [1, 2, 3] -//// |> from -//// |> list(int) -//// |> expect:equal(_, Ok([1, 2, 3])) - -//// let _ = [[1], [2], [3]] -//// |> from -//// |> list(list(int)) -//// |> expect:equal(_, Ok([1, 2, 3])) - -//// let _ = 1 -//// |> from -//// |> list(string) -//// |> expect:is_error - -//// let _ = 1.0 -//// |> from() -//// |> list(int) -//// |> expect:is_error - -//// let _ = [""] -//// |> from() -//// |> list(int) -//// |> expect:is_error - -//// [from(1), any:from("not an int")] -//// |> from -//// |> list(int) -//// |> expect:is_error -//// } +test list { + [] + |> from + |> list(_, string) + |> expect:equal(_, Ok([])) + + [] + |> from + |> list(_, int) + |> expect:equal(_, Ok([])) + + [1, 2, 3] + |> from + |> list(_, int) + |> expect:equal(_, Ok([1, 2, 3])) + + [[1], [2], [3]] + |> from + |> list(_, list(_, int)) + |> expect:equal(_, Ok([[1], [2], [3]])) + + 1 + |> from + |> list(_, string) + |> expect:is_error + + 1.0 + |> from + |> list(_, int) + |> expect:is_error + + [""] + |> from + |> list(_, int) + |> expect:is_error + + [from(1), from("not an int")] + |> from + |> list(_, int) + |> expect:is_error +} pub external fn tuple(Any) -> Result({Any, Any}, String) = "gleam__stdlib" "decode_tuple" @@ -254,12 +265,16 @@ test tuple { |> from |> tuple |> result:then(_, fn(x) { - let {a, b} = x - a |> int |> result:map(_, fn(i) { {i, b} }) + x + |> tuple_module():first + |> int + |> result:map(_, fn(f) { {f, tuple_module():second(x)} }) }) |> result:then(_, fn(x) { - let {a, b} = x - b |> float |> result:map(_, fn(f) { {a, f} }) + x + |> tuple_module():second + |> float + |> result:map(_, fn(f) { {tuple_module():first(x), f} }) }) |> expect:equal(_, Ok({1, 2.0})) } diff --git a/src/gleam__stdlib.erl b/src/gleam__stdlib.erl index f377e3f..3ab9fd6 100644 --- a/src/gleam__stdlib.erl +++ b/src/gleam__stdlib.erl @@ -6,7 +6,7 @@ atom_create_from_string/1, atom_to_string/1, map_fetch/2, iodata_append/2, iodata_prepend/2, identity/1, decode_int/1, decode_string/1, decode_bool/1, decode_float/1, decode_thunk/1, - decode_tuple/1, decode_field/2]). + decode_tuple/1, decode_list/1, decode_field/2]). expect_equal(A, Expected) -> ?assertEqual(Expected, A). expect_not_equal(A, Expected) -> ?assertNotEqual(Expected, A). @@ -58,6 +58,9 @@ decode_thunk(Data) -> decode_error_msg("a zero arity function", Data). decode_tuple(Data = {_, _}) -> {ok, Data}; decode_tuple(Data) -> decode_error_msg("a 2 element tuple", Data). +decode_list(Data) when is_list(Data) -> {ok, Data}; +decode_list(Data) -> decode_error_msg("a List", Data). + decode_field(Data, Key) -> case Data of #{Key := Value} -> diff --git a/src/tuple.gleam b/src/tuple.gleam new file mode 100644 index 0000000..d437a9f --- /dev/null +++ b/src/tuple.gleam @@ -0,0 +1,23 @@ +import expect + +pub fn first(tup) { + let {a, _} = tup + a +} + +test first { + {1, 2} + |> first + |> expect:equal(_, 1) +} + +pub fn second(tup) { + let {_, a} = tup + a +} + +test second { + {1, 2} + |> second + |> expect:equal(_, 2) +} -- cgit v1.2.3