content: module Maybe where
  
  
  -- 1
  -- >>> isJust (Just 1)
  -- True
  -- >>> isJust Nothing
  -- False
  isJust :: Maybe a -> Bool
  isJust Nothing = False
  isJust _       = True
  
  
  -- >>> isNothing (Just 1)
  -- False
  -- >>> isNothing Nothing
  -- True
  isNothing :: Maybe a -> Bool
  isNothing Nothing = True
  isNothing _       = False
  
  
  -- 2
  -- >>> mayybee 0 (+1) Nothing
  -- 0
  -- >>> mayybee 0 (+1) (Just 1)
  -- 2
  mayybee :: b -> (a -> b) -> Maybe a -> b
  mayybee b _ Nothing  = b
  mayybee _ f (Just a) = f a
  
  
  -- 3
  -- >>> fromMaybe 0 Nothing
  -- 0
  -- >>> fromMaybe 0 (Just 1)
  -- 1
  fromMaybe :: a -> Maybe a -> a
  fromMaybe a ma = mayybee a id ma
  
  
  -- 4
  -- >>> listToMaybe [1, 2, 3]
  -- Just 1
  -- >>> listToMaybe []
  -- Nothing
  listToMaybe :: [a] -> Maybe a
  listToMaybe []    = Nothing
  listToMaybe (x:_) = Just x
  
  
  -- >>> maybeToList (Just 1)
  -- [1]
  -- >>> maybeToList Nothing
  -- []
  maybeToList :: Maybe a -> [a]
  maybeToList Nothing  = []
  maybeToList (Just x) = [x]
  
  
  -- 5
  -- >>> catMaybes [Just 1, Nothing, Just 2]
  -- [1, 2]
  -- >>> catMaybes [Nothing, Nothing, Nothing]
  -- []
  catMaybes :: [Maybe a] -> [a]
  catMaybes []           = []
  catMaybes (Nothing:xs) = catMaybes xs
  catMaybes (Just x:xs)  = x : catMaybes xs
  
  
  -- 6
  -- >>> flipMaybe [Just 1, Just 2, Just 3]
  -- Just [1, 2, 3]
  -- >>> flipMaybe [Just 1, Nothing, Just 3]
  -- Nothing
  flipMaybe :: [Maybe a] -> Maybe [a]
  flipMaybe []          = Just []
  flipMaybe (Nothing:_) = Nothing
  flipMaybe (Just x:xs) =
    case flipMaybe xs of
      Just ys -> Just (x:ys)
      Nothing -> Nothing
  