summaryrefslogtreecommitdiff
path: root/Haskell-book/26/MaybeT/src/Maybe.hs
blob: 4d6c9b728879fd4a588c119747225ec50e26c156 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module Maybe where

import Control.Monad
import MonadIO
import MonadTrans

newtype MaybeT m a =
    MaybeT { runMaybeT :: m (Maybe a) }

-- compare to the instance for MaybeT
instance (Functor m)
      => Functor (MaybeT m) where
        fmap f (MaybeT ma) =
            MaybeT $ (fmap . fmap) f ma

instance (Applicative m)
      => Applicative (MaybeT m) where
        pure x = MaybeT (pure (pure x))

        (MaybeT fab) <*> (MaybeT mma) = MaybeT $ (<*>) <$> fab <*> mma

instance (Monad m)
      => Monad (MaybeT m) where
        return = pure

        -- (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
        (MaybeT ma) >>= f = MaybeT $ do
            -- ma :: m (Maybe a)
            -- v :: Maybe a
            v <- ma
            case v of
                Nothing -> return Nothing
                Just y -> runMaybeT (f y)

instance MonadTrans MaybeT where
    lift = MaybeT . liftM Just

instance (MonadIO m)
  => MonadIO (MaybeT m) where
      liftIO = lift . liftIO