is there a builtin identity function somewhere or should we just write \x -> x
?
i'm often using this. is this the best way to express 'unwrap if ok'?
...
|> Result.try \x -> x
Do you have a bigger example?
Result.try
has this definition :
try : Result a err, (a -> Result b err) -> Result b err
It doesn't look to fit with your example as the callback should return a Result
oh you're right. i was forgetting a Result. i need to use type annotations more. would have helped here.
so maybe i only thought i needed an identity function. is it even useful in roc? seems necessary in other functional langs.
my general view is that demand for an identity function is usually demand for a convenience operation in an API :big_smile:
e.g. in other languages I've often found myself using filterMap identity
- but if there were a function (like keepOks
in Roc) which directly did what I wanted, I'd use that instead!
seems good to me. was just curious. turns out i didn't really need it. will re-evaluate later on maybe after doing more of the advent problems (via zig platform btw ) :big_smile:
now that we have an at least partially working File.readBytes impl, i won't need to use multiline strings either
turns out i did need to use Result.try \x -> x
here is the usage for more context. this is from my aoc 2021 day 2. without the last line it errors.
parseLine : Str -> Result Vec2 [InvalidNumStr]
parseLine = \line ->
parsers = [
\l -> parseDir l "up " {x: 0, y: -1},
\l -> parseDir l "down " {x: 0, y: 1},
\l -> parseDir l "forward " {x: 1, y: 0},
]
List.walkUntil parsers (Err InvalidNumStr) \state, f ->
when f line is
Ok v -> Break (Ok v)
Err _ -> Continue state
|> Result.try \x -> x
Yes, my bad, I re-thought about your unwrap after posting my answer and understood what you could have written. :grimacing:
But, it looked a bit confusing to me to return a Result (Result a e) e
. Here it looks like it's what returns your parseDir
, or am I missing something?
maybe parseDir
could be simplified to only return Result a e
Then you wouldn't have to unwrap if Ok
If you want to keep your parseDir
signature, you could also have written:
when f line is
Ok v -> Break v
Err _ -> Continue state
Although it would still be confusing to keep an unknown Result
after having unwrapped it with Ok v
yes i agree about the Result Result. that function needs some work. but its an improvement over what i started with. originally i was always doing all 3 parseDir
calls and them List.keepOks
followed by List.get 0
was very sad. so atleast this is an improvement.
i think the Break Ok v
is needed because the state is a Result.
initially Err InvalidNumStr
:thinking: v
should also be a Result
([Ok a, Err *]
) so compatible with Err InvalidNumStr
yes i agree. but when i remove it i get this error:
This 2nd argument to try has an unexpected type:
24│ |> Result.try \x -> x
^^^^^^^
The argument is an anonymous function of type:
{ x : Int Signed64, y : Int Signed64 } -> { x : Int Signed64,
y : Int Signed64 }
But try needs its 2nd argument to be:
{ x : Int Signed64, y : Int Signed64 } ->
Result b [InvalidNumStr]*
this was with Oct 8th build
it took me a few minutes to respond cause i had just installed Oct 10th build to check if my json parser lazy call was fixed
but that made my day2 code err with different errors
Yes, my point was to be able to remove the Result.try :sweat_smile:
i did end up removing the Result.try
btw. here's how they ended up.
parseLine : Str -> Result Vec2 [InvalidNumStr]
parseLine = \line ->
parsers = [
\l -> parseDir l "up " {x: 0, y: -1},
\l -> parseDir l "down " {x: 0, y: 1},
\l -> parseDir l "forward " {x: 1, y: 0},
]
List.walkUntil parsers (Err InvalidNumStr) \state, f ->
when f line is
Ok v -> Break (Ok v)
Err _ -> Continue state
parseDir : Str, Str, Vec2 -> Result Vec2 [NotFound, InvalidNumStr]
parseDir = \line, startsWith, v ->
Str.replaceFirst line startsWith ""
|> Result.try \r -> Str.toI64 r
|> Result.map \n -> vecMul v {x: n, y: n}
not too bad. i looked at your day 2 and like your solution better though which uses pattern matching
i wonder do you have any suggestions for cleaning this part up? would like to remove the last line somehow.
solve : Str -> { pos1 : Vec2, pos2 : Vec2 }
solve = \input ->
vecs =
Str.trim input
|> Str.split "\n"
|> List.map \line -> parseLine line
# will overflow if reached - how to panic here or stop / return error?
|> Result.withDefault {x:999999999999999, y:999999999999999}
List.mapTry
may help
Instead of getting a list of results will give you a result of a list.
oh neat. will give it a 'try' :wink:
mapTry
much better. now i can handle the error in main.
solve : Str -> Result { pos1 : Vec2, pos2 : Vec2 } [InvalidNumStr]
solve = \input ->
Str.trim input
|> Str.split "\n"
|> List.mapTry \line -> parseLine line
|> Result.map \vecs ->
...
Last updated: Jul 05 2025 at 12:14 UTC