Skip to content

Instantly share code, notes, and snippets.

@jmettes
Last active June 26, 2017 14:27
Show Gist options
  • Save jmettes/9c29d21f49ae86f336855d47a4955a8f to your computer and use it in GitHub Desktop.
Save jmettes/9c29d21f49ae86f336855d47a4955a8f to your computer and use it in GitHub Desktop.
Maybe types in haskell
-- example of a dumb function which adds one to its input, and throws exception if given 0
addOne :: Int -> Int
addOne n = case n of
0 -> error "dont add 0"
_ -> 1 + n
-- λ> 2 + (addOne 1)
-- 4
-- λ> 2 + (addOne 0)
-- *** Exception: dont add 0
-- CallStack (from HasCallStack):
-- error, called at maybe.hs:3:10 in main:Main
-- above is not desirable, because it breaks
-- and it does not compose well, don't want to have exception handling blocks...
addOneBetter :: Int -> Maybe Int
addOneBetter n = case n of
0 -> Nothing
_ -> Just (1 + n)
-- λ> addOneBetter 1
-- Just 2
-- λ> addOneBetter 0
-- Nothing
-- λ> map addOneBetter [1,2,3,0]
-- [Just 2,Just 3,Just 4,Nothing]
-- above does not break! however, Maybe types are a bit clunky:
-- λ> (addOneBetter 1) + (addOneBetter 1)
-- <interactive>:104:1: error:
-- • No instance for (Num (Maybe Int)) arising from a use of ‘+’
-- • In the expression: (addOneBetter 1) + (addOneBetter 1)
-- In an equation for ‘it’: it = (addOneBetter 1) + (addOneBetter 1)
-- '+' doesn't know how to handle Maybe types...
sumM :: Maybe Int -> Maybe Int -> Maybe Int
sumM (Just a) (Just b) = Just (a + b)
sumM Nothing (Just b) = Nothing
sumM (Just a) Nothing = Nothing
-- λ> sumM (addOneBetter 1) (addOneBetter 1)
-- Just 4
-- λ> sumM (addOneBetter 1) (addOneBetter 0)
-- Nothing
multM :: Maybe Int -> Maybe Int -> Maybe Int
multM (Just a) (Just b) = Just (a * b)
multM Nothing (Just b) = Nothing
multM (Just a) Nothing = Nothing
-- this works, but it's annoying to have to make functions work for Maybe
-- λ> (+) <$> (addOneBetter 1) <*> (addOneBetter 1)
-- Just 4
-- λ> (+) <$> (addOneBetter 1) <*> (addOneBetter 1)
-- Nothing
-- haskell has lots of tricks for abstracting more generally
main = print $ addOne 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment