|
1 | 1 | module Control.Monad.Free where |
2 | 2 |
|
3 | 3 | import Control.Monad.Trans |
| 4 | +import Control.Monad.Eff |
4 | 5 | import Data.Either |
5 | 6 |
|
6 | 7 | data Free f a = Pure a |
@@ -46,15 +47,11 @@ iterM _ (Pure a) = return a |
46 | 47 | iterM k (Free f) = k $ iterM k <$> f |
47 | 48 | iterM k (Gosub f) = f (\req recv -> iterM k (req {}) >>= (iterM k <<< recv)) |
48 | 49 |
|
49 | | -runM :: forall f m a. (Functor f, Monad m) => (f (Free f a) -> m (Free f a)) -> Free f a -> m a |
50 | | -runM k f = case resume f of |
51 | | - Left s -> k s >>= runM k |
52 | | - Right a -> return a |
53 | | - |
54 | | -foldMap :: forall f m a. (Functor f, Monad m) => (forall r. f r -> m r) -> Free f a -> m a |
55 | | -foldMap k f = case resume f of |
56 | | - Left s -> k s >>= foldMap k |
57 | | - Right a -> return a |
| 50 | +-- Note: can blow the stack! |
| 51 | +goM :: forall f m a. (Functor f, Monad m) => (f (Free f a) -> m (Free f a)) -> Free f a -> m a |
| 52 | +goM k f = case resume f of |
| 53 | + Left s -> k s >>= goM k |
| 54 | + Right a -> return a |
58 | 55 |
|
59 | 56 | 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) |
60 | 57 | resumeGosub f = f (\a g -> |
@@ -102,3 +99,23 @@ foreign import go |
102 | 99 | \ };\ |
103 | 100 | \ };\ |
104 | 101 | \}" :: forall f a. (Functor f) => (f (Free f a) -> Free f a) -> Free f a -> a |
| 102 | + |
| 103 | +foreign import goEff |
| 104 | + "function goEff(__dict_Functor) {\ |
| 105 | + \ return function(f) {\ |
| 106 | + \ return function(__copy__1) {\ |
| 107 | + \ return function(){\ |
| 108 | + \ var _1 = __copy__1;\ |
| 109 | + \ var r;\ |
| 110 | + \ tco: while (true) {\ |
| 111 | + \ r = resume(__dict_Functor)(_1);\ |
| 112 | + \ if (r.ctor === 'Data.Either.Left') {\ |
| 113 | + \ _1 = f(r.values[0])();\ |
| 114 | + \ continue tco;\ |
| 115 | + \ } else\ |
| 116 | + \ return function(){return r.values[0];};\ |
| 117 | + \ }\ |
| 118 | + \ };\ |
| 119 | + \ };\ |
| 120 | + \ };\ |
| 121 | + \}" :: forall e f a. (Functor f) => (f (Free f a) -> Eff e (Free f a)) -> Free f a -> Eff e a |
0 commit comments