diff options
Diffstat (limited to 'TraversableT.hs')
-rw-r--r-- | TraversableT.hs | 66 |
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 @@ | |||
1 | module TraversableT where | 1 | module TraversableT where |
2 | 2 | ||
3 | import Data.Traversable | 3 | import Data.Traversable |
4 | import Control.Monad (join) | 4 | import Control.Monad (join,MonadPlus(..)) |
5 | import Control.Monad.Trans.Class | ||
6 | import Control.Applicative | ||
7 | import Data.Foldable (Foldable(foldMap)) | ||
5 | 8 | ||
6 | newtype 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. | ||
12 | newtype TraversableT t m a = TraversableT { runTraversableT :: m (t a) } | ||
7 | 13 | ||
8 | instance (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)@ | ||
17 | mapTraversableT :: (m (t a) -> n (t b)) -> TraversableT t m a -> TraversableT t n b | ||
18 | mapTraversableT f m = TraversableT $ f (runTraversableT m) | ||
19 | |||
20 | |||
21 | instance (Functor m, Functor t) => Functor (TraversableT t m) where | ||
22 | fmap f = mapTraversableT $ fmap $ fmap f | ||
23 | |||
24 | instance (Foldable f, Foldable t) => Foldable (TraversableT t f) where | ||
25 | foldMap f (TraversableT a) = foldMap (foldMap f) a | ||
26 | |||
27 | instance (Traversable f, Traversable t) => Traversable (TraversableT t f) where | ||
28 | traverse f (TraversableT a) = TraversableT <$> traverse (traverse f) a | ||
29 | |||
30 | instance (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 | |||
34 | instance (Applicative m, Alternative t) => Alternative (TraversableT t m) where | ||
35 | empty = TraversableT $ pure empty | ||
36 | m <|> n = TraversableT $ (<|>) <$> runTraversableT m <*> runTraversableT n | ||
37 | |||
38 | instance (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 | ||
16 | liftT :: Monad m => t a -> TraversableT m t a | 46 | instance (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 | |||
53 | instance Applicative t => MonadTrans (TraversableT t) where | ||
54 | lift m = TraversableT $ do | ||
55 | a <- m | ||
56 | return (pure a) | ||
57 | |||
58 | liftT :: Monad m => t a -> TraversableT t m a | ||
17 | liftT = TraversableT . return | 59 | liftT = TraversableT . return |
18 | 60 | ||
19 | liftMT :: m (t a) -> TraversableT m t a | 61 | liftMT :: m (t a) -> TraversableT t m a |
20 | liftMT = TraversableT | 62 | liftMT = TraversableT |
21 | 63 | ||
64 | -- | Lift a @callCC@ operation to the new monad. | ||
65 | liftCallCC :: 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 | ||
68 | liftCallCC callCC f = TraversableT $ | ||
69 | callCC $ \c -> | ||
70 | runTraversableT (f (\a -> TraversableT $ c (pure a))) | ||
71 | |||
72 | -- | Lift a @catchError@ operation to the new monad. | ||
73 | liftCatch :: (m (t a) -> (e -> m (t a)) -> m (t a)) -> | ||
74 | TraversableT t m a -> (e -> TraversableT t m a) -> TraversableT t m a | ||
75 | liftCatch catchError m h = TraversableT $ runTraversableT m | ||
76 | `catchError` \e -> runTraversableT (h e) | ||
77 | |||
22 | 78 | ||