Skip to content

Commit e5cfaa8

Browse files
committed
Curry map
1 parent fcdf321 commit e5cfaa8

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## v0.19.1 - 2022-01-09
44

55
- The `dynamic.dynamic` function now returns a result.
6+
- The `dynamic.map` function is now curried and requires the decoders for keys
7+
and values to be supplied.
68
- The `dynamic.result`, `dynamic.optional`, `dynamic.field`, and `dynamic.list`
79
functions are now partially applied.
810

src/gleam/dynamic.gleam

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,27 @@ pub fn tuple6(
841841
/// Error(DecodeError(expected: "Map", found: "String", path: []))
842842
/// ```
843843
///
844-
pub fn map(from value: Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) {
845-
decode_map(value)
844+
pub fn map(
845+
of key_type: Decoder(k),
846+
to value_type: Decoder(v),
847+
) -> Decoder(Map(k, v)) {
848+
fn(value) {
849+
try map = decode_map(value)
850+
try pairs =
851+
map
852+
|> map.to_list
853+
|> list.try_map(fn(pair) {
854+
let #(k, v) = pair
855+
try k =
856+
key_type(k)
857+
|> map_errors(push_path(_, "keys"))
858+
try v =
859+
value_type(v)
860+
|> map_errors(push_path(_, "values"))
861+
Ok(#(k, v))
862+
})
863+
Ok(map.from_list(pairs))
864+
}
846865
}
847866

848867
if erlang {

test/gleam/dynamic_test.gleam

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,12 +699,31 @@ pub fn nested_tuples_test() {
699699
pub fn map_test() {
700700
map.new()
701701
|> dynamic.from
702-
|> dynamic.map
702+
|> dynamic.map(dynamic.string, dynamic.int)
703703
|> should.equal(Ok(map.new()))
704704

705+
map.from_list([#("a", 1), #("b", 2)])
706+
|> dynamic.from
707+
|> dynamic.map(dynamic.string, dynamic.int)
708+
|> should.equal(Ok(map.from_list([#("a", 1), #("b", 2)])))
709+
710+
map.from_list([#("a", 1), #("b", 2)])
711+
|> dynamic.from
712+
|> dynamic.map(dynamic.int, dynamic.int)
713+
|> should.equal(Error([
714+
DecodeError(expected: "Int", found: "String", path: ["keys"]),
715+
]))
716+
717+
map.from_list([#("a", 1), #("b", 2)])
718+
|> dynamic.from
719+
|> dynamic.map(dynamic.string, dynamic.string)
720+
|> should.equal(Error([
721+
DecodeError(expected: "String", found: "Int", path: ["values"]),
722+
]))
723+
705724
1
706725
|> dynamic.from
707-
|> dynamic.map
726+
|> dynamic.map(dynamic.string, dynamic.int)
708727
|> should.equal(Error([DecodeError(expected: "Map", found: "Int", path: [])]))
709728
}
710729

0 commit comments

Comments
 (0)