/
Control.purs
180 lines (131 loc) · 7.01 KB
/
Control.purs
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
module Control.Monad.Trans.Control
( class MonadTransControl
, liftWith
, restoreT
, class MonadBaseControl
, liftBaseWith
, restoreM
, defaultLiftBaseWith
, defaultRestoreM
, WriterTStT (..)
, writerTStTToTuple, tupleToWriterTStT
) where
import Prelude
import Data.Functor.Compose (Compose (..))
import Data.Either (Either (..))
import Data.Tuple (Tuple (..))
import Data.Maybe (Maybe (..))
import Data.Identity (Identity (..))
import Data.List (List)
import Data.Monoid (class Monoid, mempty)
import Control.Monad.Base (class MonadBase)
import Control.Monad.Eff (Eff)
import Control.Monad.Trans.Class (class MonadTrans, lift)
import Control.Monad.Reader.Trans (ReaderT (..))
import Control.Monad.Writer.Trans (WriterT (..), runWriterT)
import Control.Monad.State.Trans (StateT (..), runStateT)
import Control.Monad.Except.Trans (ExceptT (..), runExceptT)
-- import Control.Monad.List.Trans (ListT (..))
import Control.Monad.Maybe.Trans (MaybeT (..), runMaybeT)
import Control.Monad.RWS.Trans (RWST (..), runRWST, RWSResult (..))
class MonadTrans t <= MonadTransControl t stT | t -> stT where
liftWith :: forall m b. Monad m => ((forall a. t m a -> m (stT a)) -> m b) -> t m b
restoreT :: forall m a. Monad m => m (stT a) -> t m a
instance readerTMonadTransControl :: MonadTransControl (ReaderT r) Identity where
liftWith f = ReaderT \r -> f \(ReaderT g) -> Identity <$> g r
restoreT x = runIdentity <$> lift x
data WriterTStT w a = WriterTStT w a
instance functorWriterTStT :: Functor (WriterTStT w) where
map f (WriterTStT w x) = WriterTStT w (f x)
writerTStTToTuple :: forall w a. WriterTStT w a -> Tuple a w
writerTStTToTuple (WriterTStT w a) = Tuple a w
tupleToWriterTStT :: forall w a. Tuple a w -> WriterTStT w a
tupleToWriterTStT (Tuple a w) = WriterTStT w a
instance writerTMonadTransControl :: Monoid r => MonadTransControl (WriterT r) (WriterTStT r) where
liftWith f = lift (f (\x -> tupleToWriterTStT <$> runWriterT x))
restoreT x = WriterT (writerTStTToTuple <$> x)
instance stateTMonadTransControl :: MonadTransControl (StateT r) (WriterTStT r) where
liftWith f = StateT \s -> (\b -> Tuple b s) <$> f (\x -> tupleToWriterTStT <$> runStateT x s)
restoreT x = StateT \_ -> (writerTStTToTuple <$> x)
instance exceptTMonadTransControl :: MonadTransControl (ExceptT r) (Either r) where
liftWith f = ExceptT $ Right <$> f runExceptT
restoreT = ExceptT
-- FIXME 0.11.0's -transformers library actually exports the goods >.>
-- instance listTMonadTransControl :: MonadTransControl ListT List where
-- liftWith f = ListT $ (\x -> Cons x Nil) <$> f (\(ListT x) -> x)
-- restoreT = ListT
instance maybeTMonadTransControl :: MonadTransControl MaybeT Maybe where
liftWith f = MaybeT $ Just <$> f runMaybeT
restoreT = MaybeT
instance rwsTMonadTransControl :: Monoid w => MonadTransControl (RWST r w s) (Compose (Tuple w) (Tuple s)) where
liftWith f = RWST \r s -> (\x -> RWSResult s x mempty) <$> f (\t -> (\(RWSResult s a w) -> Compose (Tuple w (Tuple s a))) <$> runRWST t r s)
restoreT mSt = RWST \_ _ -> (\(Compose (Tuple w (Tuple s a))) -> RWSResult s a w) <$> mSt
class MonadBase base m <= MonadBaseControl base m stM | m -> stM base where
liftBaseWith :: forall b. ((forall a. m a -> base (stM a)) -> base b) -> m b
restoreM :: forall a. base (stM a) -> m a
instance effMonadBaseControl :: MonadBaseControl (Eff e) (Eff e) Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance eitherMonadBaseControl :: MonadBaseControl (Either e) (Either e) Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance tupleMonadBaseControl :: (Monoid e) => MonadBaseControl (Tuple e) (Tuple e) Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance maybeMonadBaseControl :: MonadBaseControl Maybe Maybe Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance identityMonadBaseControl :: MonadBaseControl Identity Identity Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance listMonadBaseControl :: MonadBaseControl List List Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance arrayMonadBaseControl :: MonadBaseControl Array Array Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance funcMonadBaseControl :: MonadBaseControl ((->) r) ((->) r) Identity where
liftBaseWith f = f (map Identity)
restoreM = (map runIdentity)
instance readerTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base) => MonadBaseControl base (ReaderT r m) (Compose stM Identity) where
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
instance writerTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base, Monoid r) => MonadBaseControl base (WriterT r m) (Compose stM (WriterTStT r)) where
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
instance stateTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base) => MonadBaseControl base (StateT r m) (Compose stM (WriterTStT r)) where
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
instance exceptTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base) => MonadBaseControl base (ExceptT r m) (Compose stM (Either r)) where
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
-- instance listTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base) => MonadBaseControl base (ListT m) (Compose stM Identity) where
-- liftBaseWith = defaultLiftBaseWith
-- restoreM = defaultRestoreM
instance maybeTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base) => MonadBaseControl base (MaybeT m) (Compose stM Maybe) where
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
instance rwsTMonadBaseControl :: (MonadBaseControl base m stM, Monad m, Monad base, Monoid w) => MonadBaseControl base (RWST r w s m) (Compose stM (Compose (Tuple w) (Tuple s))) where
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
defaultLiftBaseWith :: forall base m t stM stT b
. MonadBaseControl base m stM
=> Monad m
=> Monad base
=> MonadTrans t
=> MonadTransControl t stT
=> -- MonadBaseControl base (t m) (Compose stM stT)
((forall a. t m a -> base (Compose stM stT a)) -> base b) -> t m b
defaultLiftBaseWith f = liftWith \run -> liftBaseWith \runInBase -> f (\x -> Compose <$> runInBase (run x))
defaultRestoreM :: forall base m t stM stT a
. MonadBaseControl base m stM
=> Monad m
=> Monad base
=> MonadTrans t
=> MonadTransControl t stT
=> base (Compose stM stT a) -> t m a
defaultRestoreM x = restoreT (restoreM (runCompose <$> x))
runCompose :: forall f g a. Compose f g a -> f (g a)
runCompose (Compose x) = x
runIdentity :: forall a. Identity a -> a
runIdentity (Identity x) = x