Maybe is a container, union type, type constructor. So, um, what does that mean? In Elm, null and undefined are not valid types, so what do we do when we might not have something? Let's figure it out, and when it's useful.
type Maybe a = Just a | Nothing
What did you say? Mona-wanta-who-now?
Monads in Haskell can be thought of as composable computation descriptions.
How do I get something out of this thing to work with ?
> fruit = ["apple", "banana", "mango"] ["apple","banana","mango"] : List String # we know that the head of a a list will return Maybe String > listHead = List.head fruit Just "apple" : Maybe.Maybe String # ok so listHead gives us back 'Just "apple"' # Which is of type Maybe.Maybe String # So what if we want the actual tangable value. # We can't very well put Just Apple to the DOM! > Maybe.withDefault "None" (List.head fruit) "apple" : String # Here we're able leverage the Maybe module with # Maybe.withDefault which will 'unwrap' the # maybe and if it's a type Nothing, then give us the default, # otherwise it will give use the # value from the Just. # Now we have the actual string "apple" to render to the DOM. # This is a bit better than a # case expression everytime we want to unwrap a maybe
map.maybe will transform any maybe value if it’s a Just type, otherwise it will return nothing. In this way, it will take the maybe a and transform it and return a Just b or Nothing. From the source code.
Apply a function if all the arguments are
> fruit ["apple","banana","mango"] : List String # Even though these are maybe types, we are able to transform them, as long as all of them are Just values and not Nothing! > Maybe.map2 (\a b -> (a ++ ", " ++ b)) first second Just "apple, banana" : Maybe.Maybe String #And if we have a Nothing instead of a Just value > Maybe.map2 (\a b -> a ++ ", " ++ b) (List.head nope) (Just "Ted") Nothing : Maybe.Maybe String
> Maybe.andThen <function> : (a -> Maybe.Maybe b) -> Maybe.Maybe a -> Maybe.Maybe b
So what does this thing do? Let’s break it down, reading the Type annotation.
The first argument is a function, that takes ‘a’, and returns ‘Maybe b’
The second argument is value of type Maybe
> List.head tail -- TYPE MISMATCH ------------------------------ repl-temp-000.elm The argument to function `head` is causing a mismatch. 3| List.head tail ^^^^ Function `head` is expecting the argument to be: List a But it is: Maybe (List String)
> Maybe.andThen List.head tail Just "banana" : Maybe.Maybe String # Snuck a pipe operator in there on you > Maybe.andThen List.head tail \ | |> Maybe.andThen (\s -> Just (String.toUpper s)) Just "BANANA" : Maybe.Maybe String
Just`Maybe.andThen`List.head`Maybe.andThen`(\s -> Just (String.toUpper s)) -- -> Nothing #or just as bad Maybe.andThen (\s -> Just (String.toUpper s)) (Maybe.andThen List.head (Just))