Add List.mapTry

This commit is contained in:
Richard Feldman 2022-07-17 17:45:50 -04:00
parent 31f7d72ce0
commit 08ead32be9
No known key found for this signature in database
GPG key ID: 7E4127D1E4241798
2 changed files with 28 additions and 0 deletions

View file

@ -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 ->

View file

@ -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