-- | 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. module Maybe ( -- * Definition Maybe (..), -- * Common Helpers withDefault, map, map2, map3, map4, map5, -- * Chaining Maybes andThen, ) where import Data.Maybe (Maybe (..), fromMaybe) import qualified Internal.Shortcut as Shortcut -- | 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" -- -- __Note:__ This can be overused! Many cases are better handled by a @case@ -- expression. And if you end up using @withDefault@ a lot, it can be a good sign -- that a [custom type](https://guide.elm-lang.org/types/custom_types.html) -- will clean your code up quite a bit! withDefault :: a -> Maybe a -> a withDefault = Data.Maybe.fromMaybe -- | Transform a @Maybe@ value with a given function: -- -- > >>> map sqrt (Just 9) -- > Just 3 -- > >>> map sqrt Nothing -- > Nothing -- > >>> map sqrt (String.toFloat "9") -- > Just 3 -- > >>> map sqrt (String.toFloat "x") -- > Nothing map :: (a -> b) -> Maybe a -> Maybe b map = Shortcut.map -- | Apply a function if all the arguments are @Just@ a value. -- -- > >>> map2 (+) (Just 3) (Just 4) -- > Just 7 -- > >>> map2 (+) (Just 3) Nothing -- > Nothing -- > >>> map2 (+) Nothing (Just 4) -- > Nothing -- > >>> map2 (+) (String.toInt "1") (String.toInt "123") -- > Just 124 -- > >>> map2 (+) (String.toInt "x") (String.toInt "123") -- > Nothing -- > >>> map2 (+) (String.toInt "1") (String.toInt "1.3") -- > Nothing map2 :: (a -> b -> value) -> Maybe a -> Maybe b -> Maybe value map2 = Shortcut.map2 -- | map3 :: (a -> b -> c -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe value map3 = Shortcut.map3 -- | map4 :: (a -> b -> c -> d -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe value map4 = Shortcut.map4 -- | map5 :: (a -> b -> c -> d -> e -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe e -> Maybe value map5 = Shortcut.map5 -- | Chain together many computations that may fail. It is helpful to see an -- equivalent definition: -- -- > andThen :: (a -> Maybe b) -> Maybe a -> Maybe b -- > andThen callback maybe = -- > 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 parse some user input as a month: -- -- > parseMonth :: String -> Maybe Int -- > parseMonth userInput = -- > String.toInt userInput -- > |> andThen toValidMonth -- > -- > toValidMonth :: Int -> Maybe Int -- > toValidMonth month = -- > if 1 <= month && month <= 12 then -- > Just month -- > -- > else -- > Nothing -- -- In the @parseMonth' function, if 'String.toInt@ produces @Nothing@ (because -- the @userInput@ was not an integer) 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@. andThen :: (a -> Maybe b) -> Maybe a -> Maybe b andThen = Shortcut.andThen