0 | module Control.MonadRec
2 | import public Control.WellFounded
3 | import Control.Monad.Either
4 | import Control.Monad.Identity
5 | import Control.Monad.Maybe
6 | import Control.Monad.Reader
7 | import Control.Monad.RWS
8 | import Control.Monad.State
9 | import Control.Monad.Writer
12 | import Data.SnocList
13 | import public Data.Fuel
14 | import public Data.Nat
25 | size (More f) = S $
size f
28 | Sized (SnocList a) where
45 | data Step : (rel : a -> a -> Type)
55 | -> (0 prf : rel seed2 seed)
57 | -> Step rel seed st res
60 | Done : (vres : res) -> Step rel v st res
63 | Bifunctor (Step rel seed) where
64 | bimap f _ (Cont s2 prf st) = Cont s2 prf (f st)
65 | bimap _ g (Done res) = Done (g res)
67 | mapFst f (Cont s2 prf st) = Cont s2 prf (f st)
68 | mapFst _ (Done res) = Done res
70 | mapSnd _ (Cont s2 prf st) = Cont s2 prf st
71 | mapSnd g (Done res) = Done (g res)
79 | interface Monad m => MonadRec m where
91 | {0 rel : a -> a -> Type}
93 | -> (0 prf : Accessible rel seed)
95 | -> (step : (seed2 : a) -> st -> m (Step rel seed2 st b))
99 | public export %inline
101 | {auto _ : MonadRec m}
102 | -> {auto 0 _ : WellFounded a rel}
105 | -> (step : (seed2 : a) -> st -> m (Step rel seed2 st b))
107 | trWellFounded seed = tailRecM seed (wellFounded seed)
109 | public export %inline
112 | {auto _ : MonadRec m}
113 | -> {auto 0 _ : Sized a}
116 | -> (step : (v : a) -> st -> m (Step Smaller v st b))
118 | trSized x ini = tailRecM x (sizeAccessible x) ini
123 | [NonStackSafe] Monad m => MonadRec m where
124 | tailRecM seed (Access acc) init step = step seed init >>= \case
125 | Cont seed2 prf vst => tailRecM seed2 (acc seed2 prf) vst step
126 | Done vres => pure vres
133 | MonadRec Identity where
134 | tailRecM seed (Access rec) st1 f = case f seed st1 of
135 | Id (Done b) => Id b
136 | Id (Cont y prf st2) => tailRecM y (rec y prf) st2 f
139 | MonadRec Maybe where
140 | tailRecM seed (Access rec) st1 f = case f seed st1 of
142 | Just (Done b) => Just b
143 | Just (Cont y prf st2) => tailRecM y (rec y prf) st2 f
146 | MonadRec (Either e) where
147 | tailRecM seed (Access rec) st1 f = case f seed st1 of
149 | Right (Done b) => Right b
150 | Right (Cont y prf st2) => tailRecM y (rec y prf) st2 f
154 | -> (0 _ : Accessible rel x)
156 | -> (f : (v : a) -> st -> IO (Step rel v st b))
158 | trIO x acc ini f = fromPrim $
run x acc ini
163 | -> (0 _ : Accessible rel y)
167 | run y (Access rec) st1 w = case toPrim (f y st1) w of
168 | MkIORes (Done b) w2 => MkIORes b w2
169 | MkIORes (Cont y2 prf st2) w2 => run y2 (rec y2 prf) st2 w2
171 | public export %inline
184 | {auto _ : Functor m}
185 | -> (f : (v : a) -> st -> StateT s m (Step rel v st b))
188 | -> m (Step rel v (st,s) (s,b))
189 | convST f v (st1,s1) =
190 | (\(s2,stp) => bimap (,s2) (s2,) stp) <$> runStateT s1 (f v st1)
193 | MonadRec m => MonadRec (StateT s m) where
194 | tailRecM x acc ini f =
195 | ST $
\s1 => tailRecM x acc (ini,s1) (convST f)
201 | {auto _ : Functor m}
202 | -> (f : (v : a) -> st -> EitherT e m (Step rel v st b))
205 | -> m (Step rel v st (Either e b))
206 | convE f v s1 = map conv $
runEitherT (f v s1)
209 | conv : Either e (Step rel v st b) -> Step rel v st (Either e b)
210 | conv (Left err) = Done (Left err)
211 | conv (Right $
Done b) = Done (Right b)
212 | conv (Right $
Cont v2 prf st2) = Cont v2 prf st2
215 | MonadRec m => MonadRec (EitherT e m) where
216 | tailRecM x acc ini f =
217 | MkEitherT $
tailRecM x acc ini (convE f)
223 | {auto _ : Functor m}
224 | -> (f : (v : a) -> st -> MaybeT m (Step rel v st b))
227 | -> m (Step rel v st (Maybe b))
228 | convM f v s1 = map conv $
runMaybeT (f v s1)
231 | conv : Maybe (Step rel v st b) -> Step rel v st (Maybe b)
232 | conv Nothing = Done Nothing
233 | conv (Just $
Done b) = Done (Just b)
234 | conv (Just $
Cont v2 prf st2) = Cont v2 prf st2
237 | MonadRec m => MonadRec (MaybeT m) where
238 | tailRecM x acc ini f =
239 | MkMaybeT $
tailRecM x acc ini (convM f)
245 | (f : (v : a) -> st -> ReaderT e m (Step rel v st b))
249 | -> m (Step rel v st b)
250 | convR f env v s1 = runReaderT env (f v s1)
253 | MonadRec m => MonadRec (ReaderT e m) where
254 | tailRecM x acc ini f =
255 | MkReaderT $
\env => tailRecM x acc ini (convR f env)
261 | {auto _ : Functor m}
262 | -> (f : (v : a) -> st -> WriterT w m (Step rel v st b))
265 | -> m (Step rel v (st,w) (b,w))
266 | convW f v (s1,w1) =
267 | (\(stp,w2) => bimap (,w2) (,w2) stp) <$> unWriterT (f v s1) w1
270 | MonadRec m => MonadRec (WriterT w m) where
271 | tailRecM x acc ini f =
272 | MkWriterT $
\w1 => tailRecM x acc (ini,w1) (convW f)
278 | {auto _ : Functor m}
279 | -> (f : (v : a) -> st -> RWST r w s m (Step rel v st b))
283 | -> m (Step rel v (st,s,w) (b,s,w))
284 | convRWS f env v (st1,s1,w1) =
285 | (\(stp,s2,w2) => bimap (,s2,w2) (,s2,w2) stp) <$> unRWST (f v st1) env s1 w1
288 | MonadRec m => MonadRec (RWST r w s m) where
289 | tailRecM x acc ini f =
290 | MkRWST $
\r1,s1,w1 => tailRecM x acc (ini,s1,w1) (convRWS f r1)