ide-backend-0.10.0: TestSuite/inputs/compiler/utils/Maybes.lhs
%
% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\begin{code}
{-# OPTIONS -fno-warn-tabs #-}
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ == 708
#endif
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and
-- detab the module (please do the detabbing in a separate patch). See
-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
-- for details
module Maybes (
module Data.Maybe,
MaybeErr(..), -- Instance of Monad
failME, isSuccess,
fmapM_maybe,
orElse,
mapCatMaybes,
allMaybes,
firstJust, firstJusts,
expectJust,
maybeToBool,
MaybeT(..),
main
) where
import Control.Applicative
import Control.Monad
import Data.Maybe
infixr 4 `orElse`
\end{code}
%************************************************************************
%* *
\subsection[Maybe type]{The @Maybe@ type}
%* *
%************************************************************************
\begin{code}
maybeToBool :: Maybe a -> Bool
maybeToBool Nothing = False
maybeToBool (Just _) = True
-- | Collects a list of @Justs@ into a single @Just@, returning @Nothing@ if
-- there are any @Nothings@.
allMaybes :: [Maybe a] -> Maybe [a]
allMaybes [] = Just []
allMaybes (Nothing : _) = Nothing
allMaybes (Just x : ms) = case allMaybes ms of
Nothing -> Nothing
Just xs -> Just (x:xs)
firstJust :: Maybe a -> Maybe a -> Maybe a
firstJust (Just a) _ = Just a
firstJust Nothing b = b
-- | Takes a list of @Maybes@ and returns the first @Just@ if there is one, or
-- @Nothing@ otherwise.
firstJusts :: [Maybe a] -> Maybe a
firstJusts = foldr firstJust Nothing
\end{code}
\begin{code}
expectJust :: String -> Maybe a -> a
{-# INLINE expectJust #-}
expectJust _ (Just x) = x
expectJust err Nothing = error ("expectJust " ++ err)
\end{code}
\begin{code}
mapCatMaybes :: (a -> Maybe b) -> [a] -> [b]
mapCatMaybes _ [] = []
mapCatMaybes f (x:xs) = case f x of
Just y -> y : mapCatMaybes f xs
Nothing -> mapCatMaybes f xs
\end{code}
\begin{code}
-- | flipped version of @fromMaybe@.
orElse :: Maybe a -> a -> a
(Just x) `orElse` _ = x
Nothing `orElse` y = y
\end{code}
\begin{code}
fmapM_maybe :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
fmapM_maybe _ Nothing = return Nothing
fmapM_maybe f (Just x) = do
x' <- f x
return $ Just x'
\end{code}
%************************************************************************
%* *
\subsection[MaybeT type]{The @MaybeT@ monad transformer}
%* *
%************************************************************************
\begin{code}
newtype MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)}
instance Functor m => Functor (MaybeT m) where
fmap f x = MaybeT $ fmap (fmap f) $ runMaybeT x
instance (Monad m, Applicative m) => Applicative (MaybeT m) where
pure = return
(<*>) = ap
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return . Just
x >>= f = MaybeT $ runMaybeT x >>= maybe (return Nothing) (runMaybeT . f)
fail _ = MaybeT $ return Nothing
\end{code}
%************************************************************************
%* *
\subsection[MaybeErr type]{The @MaybeErr@ type}
%* *
%************************************************************************
\begin{code}
data MaybeErr err val = Succeeded val | Failed err
instance Functor (MaybeErr err) where
fmap = liftM
instance Applicative (MaybeErr err) where
pure = return
(<*>) = ap
instance Monad (MaybeErr err) where
return v = Succeeded v
Succeeded v >>= k = k v
Failed e >>= _ = Failed e
isSuccess :: MaybeErr err val -> Bool
isSuccess (Succeeded {}) = True
isSuccess (Failed {}) = False
failME :: err -> MaybeErr err val
failME e = Failed e
main :: IO ()
main = print $ maybeToBool Nothing
\end{code}