aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2019-03-17 22:12:37 +0000
committerLouis Pilfold <louis@lpil.uk>2019-03-17 22:12:37 +0000
commit0f0f3df21b71678504cd8c0fb0e55dfd7af5f176 (patch)
tree4a470d96b115cd2c12389523462d271db391894d
parentfbd570295cd40802127913d2b308916eefb14066 (diff)
downloadgleam_stdlib-0f0f3df21b71678504cd8c0fb0e55dfd7af5f176.tar.gz
gleam_stdlib-0f0f3df21b71678504cd8c0fb0e55dfd7af5f176.zip
Unify tuple patterns with type vars
-rw-r--r--gen/any.erl28
-rw-r--r--gen/result.erl14
-rw-r--r--src/any.gleam120
-rw-r--r--src/result.gleam12
4 files changed, 94 insertions, 80 deletions
diff --git a/gen/any.erl b/gen/any.erl
index a29ed3d..951fab9 100644
--- a/gen/any.erl
+++ b/gen/any.erl
@@ -2,7 +2,7 @@
-compile(no_auto_import).
-include_lib("eunit/include/eunit.hrl").
--export([from/1, unsafeCoerce/1, string/1, int/1, float/1, bool/1, thunk/1, tuple/1]).
+-export([from/1, unsafeCoerce/1, string/1, int/1, float/1, bool/1, thunk/1, tuple/1, field/2]).
from(A) ->
gleam__stdlib:identity(A).
@@ -66,5 +66,29 @@ tuple_test() ->
expect:equal(tuple(from({<<"ok">>, <<"ok">>})),
{ok, {from(<<"ok">>), from(<<"ok">>)}}),
expect:is_error(tuple(from({1}))),
- expect:is_error(tuple(from({1, 2, 3}))).
+ 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),
+ {ok, {1, 2.0}}).
+-endif.
+
+field(A, B) ->
+ gleam__stdlib:decode_field(A, B).
+
+-ifdef(TEST).
+field_test() ->
+ {ok, OkAtom} = atom:from_string(<<"ok">>),
+ expect:equal(field(from(#{}#{ok => 1}), OkAtom), {ok, from(1)}),
+ expect:equal(field(from(#{}#{ok => 3}#{earlier => 2}), OkAtom),
+ {ok, from(3)}),
+ expect:is_error(field(from(#{}), OkAtom)),
+ expect:is_error(field(from(1), OkAtom)),
+ expect:is_error(field(from([]), [])).
-endif.
diff --git a/gen/result.erl b/gen/result.erl
index 19d87ed..e793c6b 100644
--- a/gen/result.erl
+++ b/gen/result.erl
@@ -85,22 +85,18 @@ flatten_test() ->
then(Result, Fun) ->
case Result of
{ok, X} ->
- case Fun(X) of
- {ok, Y} ->
- {ok, Y};
+ Fun(X);
- {error, Y1} ->
- {error, Y1}
- end;
-
- {error, _} ->
- Result
+ {error, E} ->
+ {error, E}
end.
-ifdef(TEST).
then_test() ->
expect:equal(then({error, 1}, fun(X) -> {ok, X + 1} end), {error, 1}),
expect:equal(then({ok, 1}, fun(X) -> {ok, X + 1} end), {ok, 2}),
+ expect:equal(then({ok, 1}, fun(_) -> {ok, <<"type change">>} end),
+ {ok, <<"type change">>}),
expect:equal(then({ok, 1}, fun(_) -> {error, 1} end), {error, 1}).
-endif.
diff --git a/src/any.gleam b/src/any.gleam
index 41abed3..22dd0d5 100644
--- a/src/any.gleam
+++ b/src/any.gleam
@@ -1,4 +1,5 @@
import list
+import atom
import result
import expect
@@ -230,74 +231,67 @@ pub external fn tuple(Any) -> Result({Any, Any}, String)
test tuple {
{1, []}
- |> from
- |> tuple
- |> expect:equal(_, Ok({from(1), from([])}))
+ |> from
+ |> tuple
+ |> expect:equal(_, Ok({from(1), from([])}))
{"ok", "ok"}
- |> from
- |> tuple
- |> expect:equal(_, Ok({from("ok"), from("ok")}))
+ |> from
+ |> tuple
+ |> expect:equal(_, Ok({from("ok"), from("ok")}))
{1}
- |> from
- |> tuple
- |> expect:is_error
+ |> from
+ |> tuple
+ |> expect:is_error
{1, 2, 3}
- |> from
- |> tuple
- |> expect:is_error
-
-// {1, 2.0}
-// |> from
-// |> tuple
-// |> result:map(_, fn(x) {
-// let {a, b} = x
-// a |> int |> result:map(_, fn(x) { {x, b} })
-// })
-// // |> result:then(_, fn(x) {
-// // let {a, b} = x
-// // b |> float |> result:map(_, fn(x) { {a, x} })
-// // })
-// // |> expect:equal(_, Ok({1, 2.0}))
+ |> from
+ |> tuple
+ |> expect:is_error
+
+ {1, 2.0}
+ |> from
+ |> tuple
+ |> result:then(_, fn(x) {
+ let {a, b} = x
+ a |> int |> result:map(_, fn(i) { {i, b} })
+ })
+ |> result:then(_, fn(x) {
+ let {a, b} = x
+ b |> float |> result:map(_, fn(f) { {a, f} })
+ })
+ |> expect:equal(_, Ok({1, 2.0}))
}
-////// TODO: FIXME: This doesn't work anymore because atoms are no longer a thing.
-////// "Decode a field from a map, extracting a specified field.
-//////
-////// Multiple fields can be extracted and stored in a new record like so:
-//////
-////// Ok(name) <- decode:field(raw_data, \"name\") |> result:then(_, decode:string)
-////// Ok(size) <- decode:field(raw_data, \"size\") |> result:then(_, decode:int)
-////// Ok({ name = name, size = size })
-//////
-////pub external fn field(Any, a) -> Result(String, Any)
-//// = "gleam__stdlib" "field"
-
-////test field {
-//// let _ = {ok = 1}
-//// |> from
-//// |> field("ok")
-//// |> expect:equal(from(1))
-
-//// let _ = {earlier = 2, ok = 3}
-//// |> from
-//// |> field("ok")
-//// |> expect:equal(from(3))
-
-//// let _ = {}
-//// |> from
-//// |> field("ok")
-//// |> expect:is_error
-
-//// let _ = 1
-//// |> from
-//// |> field("ok")
-//// |> expect:is_error
-
-//// []
-//// |> from
-//// |> field("ok")
-//// |> expect:is_error
-////}
+pub external fn field(Any, a) -> Result(Any, String)
+ = "gleam__stdlib" "decode_field"
+
+test field {
+ let Ok(ok_atom) = atom:from_string("ok")
+
+ {ok = 1}
+ |> from
+ |> field(_, ok_atom)
+ |> expect:equal(_, Ok(from(1)))
+
+ {earlier = 2, ok = 3}
+ |> from
+ |> field(_, ok_atom)
+ |> expect:equal(_, Ok(from(3)))
+
+ {}
+ |> from
+ |> field(_, ok_atom)
+ |> expect:is_error
+
+ 1
+ |> from
+ |> field(_, ok_atom)
+ |> expect:is_error
+
+ []
+ |> from
+ |> field(_, [])
+ |> expect:is_error
+}
diff --git a/src/result.gleam b/src/result.gleam
index 18503ec..a2bd330 100644
--- a/src/result.gleam
+++ b/src/result.gleam
@@ -91,12 +91,8 @@ test flatten {
pub fn then(result, fun) {
case result {
- | Ok(x) ->
- case fun(x) {
- | Ok(y) -> Ok(y)
- | Error(y) -> Error(y)
- }
- | Error(_) -> result
+ | Ok(x) -> fun(x)
+ | Error(e) -> Error(e)
}
}
@@ -110,6 +106,10 @@ test then {
|> expect:equal(_, Ok(2))
Ok(1)
+ |> then(_, fn(_) { Ok("type change") })
+ |> expect:equal(_, Ok("type change"))
+
+ Ok(1)
|> then(_, fn(_) { Error(1) })
|> expect:equal(_, Error(1))
}