mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
Add List.mapTry
This commit is contained in:
parent
31f7d72ce0
commit
08ead32be9
2 changed files with 28 additions and 0 deletions
|
@ -38,6 +38,7 @@ interface List
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
map4,
|
map4,
|
||||||
|
mapTry,
|
||||||
dropFirst,
|
dropFirst,
|
||||||
joinMap,
|
joinMap,
|
||||||
any,
|
any,
|
||||||
|
@ -858,6 +859,32 @@ split = \elements, userSplitIndex ->
|
||||||
|
|
||||||
{ before, others }
|
{ before, others }
|
||||||
|
|
||||||
|
## Like [List.map], except the transformation function returns a [Result].
|
||||||
|
## If that function ever returns `Err`, [mapTry] immediately returns `Err`.
|
||||||
|
## If it returns `Ok` for every element, [mapTry] returns `Ok` with the transformed list.
|
||||||
|
mapTry : List elem, (elem -> Result ok err) -> Result (List ok) err
|
||||||
|
mapTry = \list, toResult ->
|
||||||
|
walkTry list [] \state, elem ->
|
||||||
|
Result.map (toResult elem) \ok ->
|
||||||
|
List.append state ok
|
||||||
|
|
||||||
|
## This is the same as `iterate` but with Result instead of [Continue, Break].
|
||||||
|
## Using `Result` saves a conditional in `mapTry`.
|
||||||
|
## It might be useful to expose this in userspace?
|
||||||
|
walkTry : List elem, state, (state, elem -> Result state err) -> Result state err
|
||||||
|
walkTry = \list, init, func ->
|
||||||
|
walkTryHelp list init func 0 (List.len list)
|
||||||
|
|
||||||
|
## internal helper
|
||||||
|
walkTryHelp : List elem, state, (state, elem -> Result state err), Nat, Nat -> Result state err
|
||||||
|
walkTryHelp = \list, state, f, index, length ->
|
||||||
|
if index < length then
|
||||||
|
when f state (List.getUnsafe list index) is
|
||||||
|
Ok nextState -> walkTryHelp list nextState f (index + 1) length
|
||||||
|
Err b -> Err b
|
||||||
|
else
|
||||||
|
Ok state
|
||||||
|
|
||||||
## Primitive for iterating over a List, being able to decide at every element whether to continue
|
## Primitive for iterating over a List, being able to decide at every element whether to continue
|
||||||
iterate : List elem, s, (s, elem -> [Continue s, Break b]) -> [Continue s, Break b]
|
iterate : List elem, s, (s, elem -> [Continue s, Break b]) -> [Continue s, Break b]
|
||||||
iterate = \list, init, func ->
|
iterate = \list, init, func ->
|
||||||
|
|
|
@ -1290,6 +1290,7 @@ define_builtins! {
|
||||||
66 LIST_APPEND_UNSAFE: "appendUnsafe"
|
66 LIST_APPEND_UNSAFE: "appendUnsafe"
|
||||||
67 LIST_SUBLIST_LOWLEVEL: "sublistLowlevel"
|
67 LIST_SUBLIST_LOWLEVEL: "sublistLowlevel"
|
||||||
68 LIST_CAPACITY: "capacity"
|
68 LIST_CAPACITY: "capacity"
|
||||||
|
69 LIST_MAP_TRY: "mapTry"
|
||||||
}
|
}
|
||||||
7 RESULT: "Result" => {
|
7 RESULT: "Result" => {
|
||||||
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue