Skip to content

Commit a1bf898

Browse files
committed
Merge branch 'topic/purescript-free' into topic/free
2 parents 497d40b + 663febf commit a1bf898

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

examples/Free.purs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ runF (PutStrLn s a) = (\_ -> a) <$> trace s
2323
runF (GetLine k) = return $ k "fake input"
2424

2525
run :: forall a. Teletype a -> Eff (trace :: Trace) a
26-
run = foldMap runF
26+
run = goEff runF
2727

2828
echo = do
2929
a <- getLine
3030
putStrLn a
3131
putStrLn "Finished"
3232

33-
main = run echo
33+
main = run $ echo

src/Control/Monad/Free.purs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module Control.Monad.Free where
22

33
import Control.Monad.Trans
4+
import Control.Monad.Eff
45
import Data.Either
56

67
data Free f a = Pure a
@@ -46,15 +47,11 @@ iterM _ (Pure a) = return a
4647
iterM k (Free f) = k $ iterM k <$> f
4748
iterM k (Gosub f) = f (\req recv -> iterM k (req {}) >>= (iterM k <<< recv))
4849

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
5855

5956
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)
6057
resumeGosub f = f (\a g ->
@@ -102,3 +99,23 @@ foreign import go
10299
\ };\
103100
\ };\
104101
\}" :: 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

Comments
 (0)