summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TraversableT.hs66
1 files changed, 61 insertions, 5 deletions
diff --git a/TraversableT.hs b/TraversableT.hs
index 6446fcc9..cd04731c 100644
--- a/TraversableT.hs
+++ b/TraversableT.hs
@@ -1,11 +1,41 @@
1module TraversableT where 1module TraversableT where
2 2
3import Data.Traversable 3import Data.Traversable
4import Control.Monad (join) 4import Control.Monad (join,MonadPlus(..))
5import Control.Monad.Trans.Class
6import Control.Applicative
7import Data.Foldable (Foldable(foldMap))
5 8
6newtype TraversableT m t a = TraversableT { runTraversableT :: m (t a) } 9-- |
10--
11-- /Note:/ this does not yield a monad unless the argument monad is commutative.
12newtype TraversableT t m a = TraversableT { runTraversableT :: m (t a) }
7 13
8instance (Monad m, Traversable t, Monad t) => Monad (TraversableT m t) where 14-- | Map between 'TraversableT' computations.
15--
16-- * @'runTraversableT' ('mapTraversableT' f m) = f ('runTraversableT' m)@
17mapTraversableT :: (m (t a) -> n (t b)) -> TraversableT t m a -> TraversableT t n b
18mapTraversableT f m = TraversableT $ f (runTraversableT m)
19
20
21instance (Functor m, Functor t) => Functor (TraversableT t m) where
22 fmap f = mapTraversableT $ fmap $ fmap f
23
24instance (Foldable f, Foldable t) => Foldable (TraversableT t f) where
25 foldMap f (TraversableT a) = foldMap (foldMap f) a
26
27instance (Traversable f, Traversable t) => Traversable (TraversableT t f) where
28 traverse f (TraversableT a) = TraversableT <$> traverse (traverse f) a
29
30instance (Applicative m,Applicative t) => Applicative (TraversableT t m) where
31 pure a = TraversableT $ pure (pure a)
32 f <*> v = TraversableT $ (<*>) <$> runTraversableT f <*> runTraversableT v
33
34instance (Applicative m, Alternative t) => Alternative (TraversableT t m) where
35 empty = TraversableT $ pure empty
36 m <|> n = TraversableT $ (<|>) <$> runTraversableT m <*> runTraversableT n
37
38instance (Monad m, Traversable t, Monad t) => Monad (TraversableT t m) where
9 return = TraversableT . return . return 39 return = TraversableT . return . return
10 m >>= k = TraversableT $ do 40 m >>= k = TraversableT $ do
11 a <- runTraversableT m 41 a <- runTraversableT m
@@ -13,10 +43,36 @@ instance (Monad m, Traversable t, Monad t) => Monad (TraversableT m t) where
13 return (join b) 43 return (join b)
14 fail s = TraversableT $ return (fail s) 44 fail s = TraversableT $ return (fail s)
15 45
16liftT :: Monad m => t a -> TraversableT m t a 46instance (Monad m, Traversable t, MonadPlus t) => MonadPlus (TraversableT t m) where
47 mzero = TraversableT $ return mzero
48 m `mplus` n = TraversableT $ do
49 a <- runTraversableT m
50 b <- runTraversableT n
51 return (a `mplus` b)
52
53instance Applicative t => MonadTrans (TraversableT t) where
54 lift m = TraversableT $ do
55 a <- m
56 return (pure a)
57
58liftT :: Monad m => t a -> TraversableT t m a
17liftT = TraversableT . return 59liftT = TraversableT . return
18 60
19liftMT :: m (t a) -> TraversableT m t a 61liftMT :: m (t a) -> TraversableT t m a
20liftMT = TraversableT 62liftMT = TraversableT
21 63
64-- | Lift a @callCC@ operation to the new monad.
65liftCallCC :: Applicative t =>
66 ((( (t a) -> m (t b)) -> m (t a)) -> m (t a)) ->
67 ((a -> TraversableT t m b) -> TraversableT t m a) -> TraversableT t m a
68liftCallCC callCC f = TraversableT $
69 callCC $ \c ->
70 runTraversableT (f (\a -> TraversableT $ c (pure a)))
71
72-- | Lift a @catchError@ operation to the new monad.
73liftCatch :: (m (t a) -> (e -> m (t a)) -> m (t a)) ->
74 TraversableT t m a -> (e -> TraversableT t m a) -> TraversableT t m a
75liftCatch catchError m h = TraversableT $ runTraversableT m
76 `catchError` \e -> runTraversableT (h e)
77
22 78