A Result is the result of a computation that may fail. This is a great
way to manage errors in Elm.
Apply a function to a result. If the result is Ok, it will be converted.
If the result is an Err, the same error value will propagate through.
map sqrt (Ok 4.0) == Ok 2.0
map sqrt (Err "bad input") == Err "bad input"Apply a function to two results, if both results are Ok. If not,
the first argument which is an Err will propagate through.
map2 (+) (String.toInt "1") (String.toInt "2") == Ok 3
map2 (+) (String.toInt "1") (String.toInt "y") == Err "could not convert string 'y' to an Int"
map2 (+) (String.toInt "x") (String.toInt "y") == Err "could not convert string 'x' to an Int"Chain together a sequence of computations that may fail. It is helpful to see its definition:
andThen : Result e a -> (a -> Result e b) -> Result e b
andThen result callback =
case result of
Ok value -> callback value
Err msg -> Err msgThis means we only continue with the callback if things are going well. For
example, say you need to use (toInt : String -> Result String Int) to parse
a month and make sure it is between 1 and 12:
toValidMonth : Int -> Result String Int
toValidMonth month =
if month >= 1 && month <= 12
then Ok month
else Err "months must be between 1 and 12"
toMonth : String -> Result String Int
toMonth rawString =
toInt rawString `andThen` toValidMonth
-- toMonth "4" == Ok 4
-- toMonth "9" == Ok 9
-- toMonth "a" == Err "cannot parse to an Int"
-- toMonth "0" == Err "months must be between 1 and 12"This allows us to come out of a chain of operations with quite a specific error message. It is often best to create a custom type that explicitly represents the exact ways your computation may fail. This way it is easy to handle in your code.
Convert to a simpler Maybe if the actual error message is not needed or
you need to interact with some code that primarily uses maybes.
parseInt : String -> Result ParseError Int
maybeParseInt : String -> Maybe Int
maybeParseInt string =
toMaybe (parseInt string)Convert from a simple Maybe to interact with some code that primarily
uses Results.
parseInt : String -> Maybe Int
resultParseInt : String -> Result String Int
resultParseInt string =
fromMaybe ("error parsing string: " ++ toString string) (parseInt string)Format the error value of a result. If the result is Ok, it stays exactly
the same, but if the result is an Err we will format the error. For example,
say the errors we get have too much information:
parseInt : String -> Result ParseError Int
type ParseError =
{ message : String
, code : Int
, position : (Int,Int)
}
formatError .message (parseInt "123") == Ok 123
formatError .message (parseInt "abc") == Err "char 'a' is not a number"
A
Resultis eitherOkmeaning the computation succeeded, or it is anErrmeaning that there was some failure.