Skip to content

Instantly share code, notes, and snippets.

@nonowarn
Created December 25, 2009 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nonowarn/263730 to your computer and use it in GitHub Desktop.
Save nonowarn/263730 to your computer and use it in GitHub Desktop.
Folding Maybe
import System.Directory
orElse :: Maybe a -> Maybe a -> Maybe a
orElse x y = maybe y Just x
orElseM :: (Monad m) => m (Maybe a) -> m (Maybe a) -> m (Maybe a)
orElseM x y = maybe y (return . Just) =<< x
findJust :: [Maybe a] -> Maybe a
findJust = foldr orElse Nothing
findJustM :: (Monad m) => [m (Maybe a)] -> m (Maybe a)
findJustM = foldr orElseM (return Nothing)
tryReadFile :: FilePath -> IO (Maybe String)
tryReadFile fp = do
exists <- doesFileExist fp
if exists then fmap Just (readFile fp) else return Nothing
-- *Main> tryReadFile "foo" `orElseM` tryReadFile "bar"
-- Nothing
-- *Main> :! echo 1 > bar
-- *Main> tryReadFile "foo" `orElseM` tryReadFile "bar"
-- Just "1\n"
-- *Main> findJustM [tryReadFile "foo", tryReadFile "bar", tryReadFile "baz"]
-- Just "1\n"
-- *Main> findJustM [tryReadFile "foo", tryReadFile "baz", tryReadFile "quux"]
-- Nothing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment