1
1
module Control.Monad.Free where
2
2
3
3
import Prelude
4
+ import Data.Either
4
5
import Control.Monad.Trans
5
6
6
- data Free f a = Pure a | Free (f (Free f a ))
7
+ data Free f a = Pure a
8
+ | Free (f (Free f a ))
9
+ | Gosub (forall s . (forall r . ({ } -> Free f r ) -> (r -> Free f a ) -> s ) -> s )
7
10
8
11
class MonadFree f m where
9
12
wrap :: forall a . f (m a ) -> m a
10
13
11
14
instance functorFree :: (Functor f ) => Functor (Free f ) where
12
- (<$>) f = go where
13
- go (Pure a) = Pure (f a)
14
- go (Free fa) = Free (go <$> fa)
15
+ (<$>) f (Pure a) = Pure (f a)
16
+ (<$>) f g = liftA1 f g
15
17
16
18
instance applyFree :: (Functor f ) => Apply (Free f ) where
17
19
(<*>) = ap
@@ -20,8 +22,8 @@ instance applicativeFree :: (Functor f) => Applicative (Free f) where
20
22
pure = Pure
21
23
22
24
instance bindFree :: (Functor f ) => Bind (Free f ) where
23
- (>>=) (Pure a ) f = f a
24
- (>>=) ( Free m) f = Free ((<$>) (\a -> a >>= f) m )
25
+ (>>=) (Gosub g ) f = Gosub (\h -> g (\a i -> h a (\x -> Gosub (\j -> j (const (i x)) f))))
26
+ (>>=) a f = Gosub (\h -> h (const a) f )
25
27
26
28
instance monadFree :: (Functor f ) => Monad (Free f )
27
29
@@ -36,6 +38,58 @@ instance monadFreeFree :: (Functor f) => MonadFree f (Free f) where
36
38
liftF :: forall f m a . (Functor f , Monad m , MonadFree f m ) => f a -> m a
37
39
liftF fa = wrap $ return <$> fa
38
40
41
+ pureF :: forall f a . (Applicative f ) => a -> Free f a
42
+ pureF a = Free (pure (Pure a))
43
+
44
+ -- Note: can blow the stack!
39
45
iterM :: forall f m a . (Functor f , Monad m ) => (f (m a ) -> m a ) -> Free f a -> m a
40
46
iterM _ (Pure a) = return a
41
- iterM k (Free f) = k $ (iterM k) <$> f
47
+ iterM k (Free f) = k $ iterM k <$> f
48
+ iterM k (Gosub f) = iterM k $ f (\req recv -> req {} >>= recv)
49
+
50
+ resumeGosub :: forall f a . (Functor f ) => (forall s . (forall r . ({ } -> Free f r ) -> (r -> Free f a ) -> s ) -> s ) -> Either (f (Free f a )) (Free f a )
51
+ resumeGosub f = f (\a g ->
52
+ case a {} of
53
+ Pure a -> Right (g a)
54
+ Free t -> Left ((\h -> h >>= g) <$> t)
55
+ Gosub h -> Right (h (\b i -> b {} >>= (\x -> i x >>= g)))
56
+ )
57
+
58
+ foreign import resume
59
+ " function resume(__dict_Functor) {\
60
+ \ return function(__copy__1) {\
61
+ \ var _1 = __copy__1;\
62
+ \ tco: while (true)\
63
+ \ if (_1.ctor === 'Control.Monad.Free.Pure')\
64
+ \ return Data_Either.Right(_1.values[0]);\
65
+ \ else if (_1.ctor === 'Control.Monad.Free.Free')\
66
+ \ return Data_Either.Left(_1.values[0]);\
67
+ \ else {\
68
+ \ var x = resumeGosub(__dict_Functor)(_1.values[0]);\
69
+ \ if (x.ctor === 'Data.Either.Left')\
70
+ \ return x;\
71
+ \ else {\
72
+ \ _1 = x.values[0];\
73
+ \ continue tco;\
74
+ \ }\
75
+ \ }\
76
+ \ };\
77
+ \}" :: forall f a . (Functor f ) => Free f a -> Either (f (Free f a )) a
78
+
79
+ foreign import go
80
+ " function go(__dict_Functor) {\
81
+ \ return function(f) {\
82
+ \ return function(__copy__1) {\
83
+ \ var _1 = __copy__1;\
84
+ \ var r;\
85
+ \ tco: while (true) {\
86
+ \ r = resume(__dict_Functor)(_1);\
87
+ \ if (r.ctor === 'Data.Either.Left') {\
88
+ \ _1 = f(r.values[0]);\
89
+ \ continue tco;\
90
+ \ } else\
91
+ \ return r.values[0];\
92
+ \ }\
93
+ \ };\
94
+ \ };\
95
+ \}" :: forall f a . (Functor f ) => (f (Free f a ) -> Free f a ) -> Free f a -> a
0 commit comments