elm-lang/core/2.0.0

NOTE: this package moved to elm/core

NOTE: this package is not compatible with Elm 0.19.1

Maybe

This library fills a bunch of important niches in Elm. A Maybe can help you with optional arguments, error handling, and records with optional fields.

Definition

type Maybe a
= Just a
| Nothing

Represent values that may or may not exist. It can be useful if you have a record field that is only filled in sometimes. Or if a function takes a value sometimes, but does not absolutely need it.

-- A person, but maybe we do not know their age.
type alias Person =
    { name : String
    , age : Maybe Int
    }


tom = { name = "Tom", age = Just 42 }
sue = { name = "Sue", age = Nothing }

Common Helpers

map : (a -> b) -> Maybe a -> Maybe b

Transform an Maybe value with a given function:

map sqrt (Just 9) == Just 3
map sqrt Nothing == Nothing
withDefault : a -> Maybe a -> a

Provide a default value, turning an optional value into a normal value. This comes in handy when paired with functions like Dict.get which gives back a Maybe.

withDefault 100 (Just 42)   -- 42
withDefault 100 Nothing     -- 100


withDefault "unknown" (Dict.get "Tom" Dict.empty)   -- "unknown"
oneOf : List (Maybe a) -> Maybe a

Pick the first Maybe that actually has a value. Useful when you want to try a couple different things, but there is no default value.

oneOf [ Nothing, Just 42, Just 71 ] == Just 42
oneOf [ Nothing, Nothing, Just 71 ] == Just 71
oneOf [ Nothing, Nothing, Nothing ] == Nothing

Chaining Maybes

andThen : Maybe a -> (a -> Maybe b) -> Maybe b

Chain together many computations that may fail. It is helpful to see its definition:

andThen : Maybe a -> (a -> Maybe b) -> Maybe b
andThen maybe callback =
    case maybe of
      Just value -> callback value
      Nothing -> Nothing

This means we only continue with the callback if things are going well. For example, say you need to use (toInt : String -> Maybe Int) to parse a month and make sure it is between 1 and 12:

toValidMonth : Int -> Maybe Int
toValidMonth month =
    if month >= 1 && month <= 12
        then Just month
        else Nothing


toMonth : String -> Maybe Int
toMonth rawString =
    toInt rawString `andThen` toValidMonth

If toInt fails and results in Nothing this entire chain of operations will short-circuit and result in Nothing. If toValidMonth results in Nothing, again the chain of computations will result in Nothing.