Convenience functions for working with Result
.
isOk : Result e a -> Basics.Bool
Check whether the result is Ok
without unwrapping it.
isErr : Result e a -> Basics.Bool
Check whether the result is Err
without unwrapping it.
extract : (e -> a) -> Result e a -> a
Turn a Result e a
to an a
, by applying the conversion
function specified to the e
.
unwrap : b -> (a -> b) -> Result e a -> b
Convert a Result e a
to a b
by applying a function if
the Result
is Ok
or using the provided default value if it
is an Err
.
unpack : (e -> b) -> (a -> b) -> Result e a -> b
Convert a Result e a
to a b
by applying either the first
function if the Result
is an Err
or the second function if the
Result
is Ok
. Both of these functions must return the same type.
error : Result e a -> Maybe e
Convert to a Maybe containing the error, if there is one.
parseInt : String -> Result ParseError Int
maybeParseError : String -> Maybe ParseError
maybeParseError string =
error (parseInt string)
mapBoth : (e -> f) -> (a -> b) -> Result e a -> Result f b
Apply the first argument function to an Err
and the second
argument function to an Ok
of a Result
.
merge : Result a a -> a
Eliminate Result when error and success have been mapped to the same type, such as a message type.
merge (Ok 4) == 4
merge (Err -1) == -1
More pragmatically:
type Msg
= UserTypedInt Int
| UserInputError String
msgFromInput : String -> Msg
msgFromInput =
String.toInt
>> Result.mapError UserInputError
>> Result.map UserTypedInt
>> Result.Extra.merge
join : Result x (Result x a) -> Result x a
Join contained results with the same error into one result.
Usefull if you have a "result in a result":
join <| Ok (Ok 4) == Ok 4
join <| Ok (Err "message") == Err "message"
partition : List (Result e a) -> ( List a, List e )
Partition a list of Results into two lists of values (successes and failures), much as List.partition takes a predicate and splits a list based on whether the predicate indicates success or failure.
partition ( Ok 4, Err "no", Err "hi" ) == ( [ 4 ], [ "no", "hi" ] )
partition ( Err 7.1, Ok 'k', Err 9.0, Ok 'p' ) == ( [ 'k', 'p' ], [ 7.1, 9.0 ] )
filter : e -> (a -> Basics.Bool) -> Result e a -> Result e a
Take a Result
and a predicate function and return a Result
with the
original value when a predicate matches.
filter "is not 1" (\v -> v == 1) (Ok 1) == Ok 1
filter "is not 2" (\v -> v == 2) (Ok 1) == Err "is not 2"
combine : List (Result x a) -> Result x (List a)
Combine a list of results into a single result (holding a list).
Also known as sequence
on lists.
combineMap : (a -> Result x b) -> List a -> Result x (List b)
Map a function producing results on a list
and combine those into a single result (holding a list).
Also known as traverse
on lists.
combineMap f xs == combine (List.map f xs)
combineFirst : ( Result x a, c ) -> Result x ( a, c )
Pull a result out of the first element of a tuple and combine it into a result holding the tuple's values.
combineSecond : ( c, Result x a ) -> Result x ( c, a )
Pull a result out of the second element of a tuple
and combine it into a result holding the tuple's values.
Also known as sequence
on tuples.
combineBoth : ( Result x a, Result x b ) -> Result x ( a, b )
Combine all results in a tuple
into a single result holding the tuple's values.
Also know as bisequence
on tuples.
combineMapFirst : (a -> Result x b) -> ( a, c ) -> Result x ( b, c )
Map a function producing results on the first element of a tuple
and then pull it out using combineFirst
.
Also know as sequence
on tuples.
combineMapFirst f ( x, y )
== combineFirst (Tuple.mapFirst f ( x, y ))
== Result.map (\newX -> ( newX, y )) (f x)
combineMapSecond : (a -> Result x b) -> ( c, a ) -> Result x ( c, b )
Map a function producing results on the second element of a tuple
and then pull it out using combineSecond
.
Also know as traverse
on tuples.
combineMapSecond f ( x, y )
== combineSecond (Tuple.mapSecond f ( x, y ))
== Result.map (Tuple.pair x) (f y)
combineMapBoth : (a -> Result x c) -> (b -> Result x d) -> ( a, b ) -> Result x ( c, d )
Map a function producing results on the both elements of a tuple
and then pull them out using combineBoth
.
Also know as bitraverse
on tuples.
combineMapBoth f g ( x, y )
== combineBoth (Tuple.mapBoth f g ( x, y ))
== Result.map2 Tuple.pair (f x) (g y)
singleton : a -> Result e a
Create a singleton
from a value to an Result
with a Ok
of the same type. Also known as pure
. You can use the Err
constructor for a singleton of the Err
variety.
singleton 2 == Ok 2
andMap : Result e a -> Result e (a -> b) -> Result e b
Apply the function that is inside Result
to a value that is inside
Result
. Return the result inside Result
. If one of the Result
arguments is Err e
, return Err e
. Also known as apply
.
Err "Oh" |> andMap (Err "No!") == Err "Oh"
Err "Oh" |> andMap (Ok 2) == Err "Oh"
Ok ((+) 1) |> andMap (Err "No!") == Err "No!"
Ok ((+) 1) |> andMap (Ok 2) == Ok 3
or : Result e a -> Result e a -> Result e a
Like the Boolean ||
this will return the first value that is
positive (Ok
). However, unlike with ||
, both values will be
computed anyway (there is no short-circuiting).
or (Ok 4) (Ok 5) == Ok 4
or (Err "Oh!") (Ok 5) == Ok 5
or (Ok 4) (Err "No!") == Ok 4
or (Err "Oh!") (Err "No!") == Err "No!"
As the last example line shows, the second error is returned if both results are erroneous.
orLazy : Result e a -> (() -> Result e a) -> Result e a
Non-strict version of or
. The second argument will only be
evaluated if the first argument is an Err
.
orElseLazy : (() -> Result e a) -> Result e a -> Result e a
Piping-friendly version of orLazy
. The first argument will only
be evaluated if the second argument is an Err
. Example use:
String.toInt "Hello"
|> orElseLazy (\() -> String.toInt "42")
orElse : Result e a -> Result e a -> Result e a
Strict version of orElseLazy
(and at the same time,
piping-friendly version of or
).
orElse (Ok 4) (Ok 5) == Ok 5 -- crucial difference from `or`
orElse (Err "Oh!") (Ok 5) == Ok 5
orElse (Ok 4) (Err "No!") == Ok 4
orElse (Err "Oh!") (Err "No!") == Err "Oh!" -- also different from `or`
Also:
String.toInt "Hello"
|> orElse (String.toInt "42")
toTask : Result x a -> Task x a
Convert a Result
to a Task
that will fail or succeed immediately.
toTask (Ok 4) == Task.succeed 4
toTask (Err "msg") == Task.fail "msg"
This can be helpful when the value of a succeeding Task needs to be decoded, but
a failure to decode should result in a failing Task
, not a succeeding Task
containing a Result.Err
:
andThenDecode : (a -> Result x b) -> Task x a -> Task x b andThenDecode decode = Task.andThen (decode >> Result.Extra.toTask)