blob: e09bfe6a38fbbfab68da7c0a22809030aec639ff (
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
module Either where
import Control.Monad (liftM)
import MonadTrans
import MonadIO
newtype EitherT e m a =
EitherT { runEitherT :: m (Either e a) }
-- 1
instance Functor m => Functor (EitherT e m) where
fmap f (EitherT x) = EitherT $ (fmap . fmap) f x
-- 2
instance Applicative m => Applicative (EitherT e m) where
pure x = EitherT $ pure $ pure x
(EitherT f) <*> (EitherT a) = EitherT $ (<*>) <$> f <*> a
-- 3
instance Monad m => Monad (EitherT e m) where
return = pure
(EitherT em) >>= f = EitherT $ do
v <- em
case v of
Left y -> return $ Left y
Right y -> runEitherT (f y)
-- 4
-- transformer version of swapEither.
-- Hint: write swapEither first, then swapEitherT in terms of the former.
swapEither :: Either e a -> Either a e
swapEither (Left x) = Right x
swapEither (Right y) = Left y
swapEitherT :: (Functor m)
=> EitherT e m a
-> EitherT a m e
swapEitherT (EitherT x) = EitherT $ fmap swapEither x
-- 5. Write the transformer variant of the either catamorphism.
eitherT :: Monad m
=> (a -> m c)
-> (b -> m c)
-> EitherT a m b
-> m c
eitherT f g (EitherT x) = x >>= (either f g)
instance MonadTrans (EitherT e) where
lift = EitherT . liftM Right
instance (MonadIO m)
=> MonadIO (EitherT e m) where
liftIO = lift . liftIO
|