@@ -0,0 +1,83 @@
1+{-# LANGUAGE MultiParamTypeClasses #-}
2+{-# LANGUAGE TypeFamilies #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE FlexibleContexts #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+module Control.Monad.Ether.Reader
8+ ( module Control.Monad.Ether.Reader
9+ , module Control.Monad.Trans.Ether.Reader
10+ ) where
11+
12+import Data.Proxy (Proxy(Proxy))
13+import Control.Monad.Trans (lift)
14+
15+import Control.Ether.Core (EtherData)
16+import Control.Monad.Trans.Ether.Reader
17+
18+-- for mtl instances
19+import qualified Control.Monad.Trans.Cont as Cont (ContT , liftLocal)
20+import qualified Control.Monad.Trans.Except as Except (ExceptT , mapExceptT)
21+import qualified Control.Monad.Trans.Identity as Identity (IdentityT, mapIdentityT)
22+import qualified Control.Monad.Trans.List as List (ListT , mapListT)
23+import qualified Control.Monad.Trans.Maybe as Maybe (MaybeT , mapMaybeT)
24+import qualified Control.Monad.Trans.State.Lazy as State.Lazy (StateT , mapStateT)
25+import qualified Control.Monad.Trans.State.Strict as State.Strict (StateT , mapStateT)
26+import qualified Control.Monad.Trans.Writer.Lazy as Writer.Lazy (WriterT , mapWriterT)
27+import qualified Control.Monad.Trans.Writer.Strict as Writer.Strict (WriterT , mapWriterT)
28+
29+class Monad m => MonadEtherReader tag m where
30+
31+ etherLocal :: proxy tag -> (EtherData tag -> EtherData tag) -> m a -> m a
32+
33+ etherAsk :: proxy tag -> m (EtherData tag)
34+ etherAsk proxy = etherReader proxy id
35+
36+ etherReader :: proxy tag -> (EtherData tag -> a) -> m a
37+ etherReader proxy f = fmap f (etherAsk proxy)
38+
39+instance {-# OVERLAPS #-} Monad m => MonadEtherReader tag (EtherReaderT tag m) where
40+ etherAsk proxy = etherReaderT proxy return
41+ etherLocal proxy f m = etherReaderT proxy (runEtherReaderT proxy m . f)
42+
43+instance MonadEtherReader tag m => MonadEtherReader tag (EtherReaderT tag' m) where
44+ etherAsk proxy = lift (etherAsk proxy)
45+ etherLocal proxy = mapEtherReaderT Proxy . etherLocal proxy
46+
47+-- Instances for mtl transformers
48+
49+instance MonadEtherReader tag m => MonadEtherReader tag (Cont.ContT r m) where
50+ etherAsk proxy = lift (etherAsk proxy)
51+ etherLocal proxy = Cont.liftLocal (etherAsk proxy) (etherLocal proxy)
52+
53+instance MonadEtherReader tag m => MonadEtherReader tag (Except.ExceptT e m) where
54+ etherAsk proxy = lift (etherAsk proxy)
55+ etherLocal proxy = Except.mapExceptT . etherLocal proxy
56+
57+instance MonadEtherReader tag m => MonadEtherReader tag (Identity.IdentityT m) where
58+ etherAsk proxy = lift (etherAsk proxy)
59+ etherLocal proxy = Identity.mapIdentityT . etherLocal proxy
60+
61+instance MonadEtherReader tag m => MonadEtherReader tag (List.ListT m) where
62+ etherAsk proxy = lift (etherAsk proxy)
63+ etherLocal proxy = List.mapListT . etherLocal proxy
64+
65+instance MonadEtherReader tag m => MonadEtherReader tag (Maybe.MaybeT m) where
66+ etherAsk proxy = lift (etherAsk proxy)
67+ etherLocal proxy = Maybe.mapMaybeT . etherLocal proxy
68+
69+instance MonadEtherReader tag m => MonadEtherReader tag (State.Lazy.StateT s m) where
70+ etherAsk proxy = lift (etherAsk proxy)
71+ etherLocal proxy = State.Lazy.mapStateT . etherLocal proxy
72+
73+instance MonadEtherReader tag m => MonadEtherReader tag (State.Strict.StateT s m) where
74+ etherAsk proxy = lift (etherAsk proxy)
75+ etherLocal proxy = State.Strict.mapStateT . etherLocal proxy
76+
77+instance (Monoid w, MonadEtherReader tag m) => MonadEtherReader tag (Writer.Lazy.WriterT w m) where
78+ etherAsk proxy = lift (etherAsk proxy)
79+ etherLocal proxy = Writer.Lazy.mapWriterT . etherLocal proxy
80+
81+instance (Monoid w, MonadEtherReader tag m) => MonadEtherReader tag (Writer.Strict.WriterT w m) where
82+ etherAsk proxy = lift (etherAsk proxy)
83+ etherLocal proxy = Writer.Strict.mapWriterT . etherLocal proxy