0 | module Control.Monad.Free
2 | import Control.MonadRec
17 | data Free : (f : Type -> Type) -> (a : Type) -> Type
23 | data FreeView : (f : Type -> Type) -> (a : Type) -> Type
28 | 0 Arrs : (f : Type -> Type) -> (a,b : Type) -> Type
32 | -> (view : FreeView f t)
33 | -> (arrs : Arrs f t a)
37 | Pure : (val : a) -> FreeView f a
38 | Bind : (f b) -> (b -> Free f a) -> FreeView f a
40 | Arrs = TCQueue . Free
44 | fromView : FreeView f a -> Free f a
45 | fromView f = MkFree f empty
47 | concatF : Free f a -> Arrs f a b -> Free f b
48 | concatF (MkFree v r) l = MkFree v (r ++ l)
53 | toView : Free f a -> FreeView f a
54 | toView (MkFree v s) = case v of
55 | Pure val => case uncons s of
57 | (h :| t) => assert_total $
toView (concatF (h val) t)
59 | Bind x k => Bind x (\va => concatF (k va) s)
65 | bind : Free f a -> (a -> Free f b) -> Free f b
66 | bind (MkFree v r) g = MkFree v $
snoc r g
69 | Functor (Free f) where
70 | map g fr = bind fr (fromView . Pure . g)
73 | Applicative (Free f) where
74 | pure = fromView . Pure
75 | f <*> v = bind f (\f => map (f $
) v)
77 | public export %inline
78 | Monad (Free f) where
82 | MonadRec (Free f) where
83 | tailRecM seed (Access rec) vst step = do
84 | Cont s2 prf vst2 <- step seed vst
86 | tailRecM s2 (rec s2 prf) vst2 step
90 | lift : f a -> Free f a
91 | lift v = fromView (Bind v pure)
94 | HasIO m => HasIO (Free m) where
95 | liftIO = lift . liftIO
102 | wrap : f (Free f a) -> Free f a
103 | wrap x = fromView (Bind x id)
106 | substFree : (forall x . f x -> Free g x) -> Free f a -> Free g a
107 | substFree k f = case toView f of
109 | Bind g i => assert_total $
bind (k g) (substFree k . i)
115 | (forall b. f b -> (b -> Free f a) -> r)
119 | resume' k j fr = case toView fr of
126 | resume : Functor f => Free f a -> Either (f (Free f a)) a
127 | resume fr = case toView fr of
129 | Bind g i => Left $
map i g
133 | mapK : (f : forall t . m t -> n t) -> Free m a -> Free n a
134 | mapK f = substFree (lift . f)
139 | foldMap : MonadRec m => (forall x . f x -> m x) -> Free f a -> m a
140 | foldMap k fr = assert_total $
trSized forever fr $
\fu,frm => case fu of
141 | More x => case toView frm of
142 | Pure val => Done <$> pure val
143 | Bind g i => Cont x (reflexive {rel = LTE}) . i <$> k g
144 | Dry => idris_crash "Control.Monad.Free.foldFree: ran out of fuel"
148 | run : Free I a -> a
149 | run fr = case toView fr of
151 | Bind v f => run (assert_smaller fr $
f v)
155 | {auto _ : Functor m}
156 | -> {auto _ : MonadRec n}
161 | runM g free = assert_total $
trSized forever free $
\fu,fr => case fu of
162 | More x => case resume fr of
163 | Right va => pure (Done va)
164 | Left ma => Cont x (reflexive {rel = LTE}) <$> g ma
165 | Dry => idris_crash "Control.Monad.Free.runM: ran out of fuel"