Skip to content

Commit 23fa9a9

Browse files
committed
Adding FreeC
1 parent 83112f8 commit 23fa9a9

File tree

4 files changed

+124
-18
lines changed

4 files changed

+124
-18
lines changed

MODULE.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,86 @@
11
# Module Documentation
22

3+
## Module Data.Coyoneda
4+
5+
### Types
6+
7+
newtype Coyoneda f a where
8+
Coyoneda :: Exists (CoyonedaF f a) -> Coyoneda f a
9+
10+
newtype CoyonedaF f a i where
11+
CoyonedaF :: { fi :: f i, k :: i -> a } -> CoyonedaF f a i
12+
13+
type Natural f g = forall a. f a -> g a
14+
15+
16+
### Type Class Instances
17+
18+
instance applicativeCoyoneda :: (Applicative f) => Applicative (Coyoneda f)
19+
20+
instance applyCoyoneda :: (Apply f) => Apply (Coyoneda f)
21+
22+
instance bindCoyoneda :: (Bind f) => Bind (Coyoneda f)
23+
24+
instance comonadCoyoneda :: (Comonad w) => Comonad (Coyoneda w)
25+
26+
instance extendCoyoneda :: (Extend w) => Extend (Coyoneda w)
27+
28+
instance functorCoyoneda :: Functor (Coyoneda f)
29+
30+
instance monadCoyoneda :: (Monad f) => Monad (Coyoneda f)
31+
32+
instance monadTransCoyoneda :: MonadTrans Coyoneda
33+
34+
35+
### Values
36+
37+
coyoneda :: forall f a b. (a -> b) -> f a -> Coyoneda f b
38+
39+
liftCoyoneda :: forall f a. f a -> Coyoneda f a
40+
41+
liftCoyonedaT :: forall f g. Natural f g -> Natural (Coyoneda f) (Coyoneda g)
42+
43+
liftCoyonedaTF :: forall f g. (Functor g) => Natural f g -> Natural (Coyoneda f) g
44+
45+
lowerCoyoneda :: forall f a. (Functor f) => Coyoneda f a -> f a
46+
47+
48+
## Module Data.Yoneda
49+
50+
### Types
51+
52+
newtype Yoneda f a where
53+
Yoneda :: forall b. (a -> b) -> f b -> Yoneda f a
54+
55+
56+
### Type Class Instances
57+
58+
instance applicativeYoneda :: (Applicative f) => Applicative (Yoneda f)
59+
60+
instance applyYoneda :: (Apply f) => Apply (Yoneda f)
61+
62+
instance bindCoyoneda :: (Bind f) => Bind (Yoneda f)
63+
64+
instance comonadYoneda :: (Comonad w) => Comonad (Yoneda w)
65+
66+
instance extendYoneda :: (Extend w) => Extend (Yoneda w)
67+
68+
instance functorYoneda :: Functor (Yoneda f)
69+
70+
instance monadTransYoneda :: MonadTrans Yoneda
71+
72+
instance monadYoneda :: (Monad f) => Monad (Yoneda f)
73+
74+
75+
### Values
76+
77+
liftYoneda :: forall f a. (Functor f) => f a -> Yoneda f a
78+
79+
lowerYoneda :: forall f a. Yoneda f a -> f a
80+
81+
runYoneda :: forall f a b. Yoneda f a -> (a -> b) -> f b
82+
83+
384
## Module Control.Monad.Free
485

586
### Types
@@ -9,6 +90,8 @@
990
Free :: f (Free f a) -> Free f a
1091
Gosub :: forall s. (forall r. (Unit -> Free f r) -> (r -> Free f a) -> s) -> s -> Free f a
1192

93+
type FreeC f a = Free (Coyoneda f) a
94+
1295

1396
### Type Classes
1497

@@ -39,14 +122,22 @@
39122

40123
goEff :: forall e f a. (Functor f) => (f (Free f a) -> Eff e (Free f a)) -> Free f a -> Eff e a
41124

125+
goEffC :: forall e f a. Natural f (Eff e) -> FreeC f a -> Eff e a
126+
42127
goM :: forall f m a. (Functor f, Monad m) => (f (Free f a) -> m (Free f a)) -> Free f a -> m a
43128

129+
goMC :: forall f m a. (Monad m) => Natural f m -> FreeC f a -> m a
130+
44131
iterM :: forall f m a. (Functor f, Monad m) => (forall a. f (m a) -> m a) -> Free f a -> m a
45132

46133
liftF :: forall f m a. (Functor f, Monad m, MonadFree f m) => f a -> m a
47134

135+
liftFC :: forall f a. f a -> FreeC f a
136+
48137
pureF :: forall f a. (Applicative f) => a -> Free f a
49138

139+
pureFC :: forall f a. (Applicative f) => a -> FreeC f a
140+
50141

51142
## Module Control.Monad.Trampoline
52143

examples/Teletype.purs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,26 @@
1-
module Teletype where
1+
module Main where
22

33
import Control.Monad.Eff
44
import Control.Monad.Free
5+
import Data.Coyoneda
56
import Debug.Trace
67

78
data TeletypeF a = PutStrLn String a | GetLine (String -> a)
89

9-
instance teletypeFFunctor :: Functor TeletypeF where
10-
(<$>) f (PutStrLn s a) = PutStrLn s (f a)
11-
(<$>) f (GetLine k) = GetLine (\s -> f (k s))
12-
13-
type Teletype = Free TeletypeF
10+
type Teletype a = FreeC TeletypeF a
1411

1512
putStrLn :: String -> Teletype Unit
16-
putStrLn s = liftF $ PutStrLn s unit
13+
putStrLn s = liftFC $ PutStrLn s unit
1714

1815
getLine :: Teletype String
19-
getLine = liftF $ GetLine (\a -> a)
16+
getLine = liftFC $ GetLine id
2017

21-
runF :: forall a. TeletypeF a -> Eff (trace :: Trace) a
22-
runF (PutStrLn s a) = (\_ -> a) <$> trace s
23-
runF (GetLine k) = return $ k "fake input"
18+
teletypeN :: forall e. Natural TeletypeF (Eff (trace :: Trace))
19+
teletypeN (PutStrLn s a) = const a <$> trace s
20+
teletypeN (GetLine k) = return $ k "fake input"
2421

2522
run :: forall a. Teletype a -> Eff (trace :: Trace) a
26-
run = goEff runF
23+
run = goEffC teletypeN
2724

2825
echo = do
2926
a <- getLine

src/Control/Monad/Free.purs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
module Control.Monad.Free
22
( Free(..)
3+
, FreeC(..)
34
, MonadFree, wrap
4-
, liftF
5-
, pureF
5+
, liftF, liftFC
6+
, pureF, pureFC
67
, iterM
7-
, goM
8+
, goM, goMC
89
, go
9-
, goEff
10+
, goEff, goEffC
1011
) where
1112

1213
import Control.Monad.Trans
1314
import Control.Monad.Eff
15+
import Data.Coyoneda
1416
import Data.Either
1517
import Data.Function
1618

1719
data Free f a = Pure a
1820
| Free (f (Free f a))
1921
| Gosub (forall s. (forall r. (Unit -> Free f r) -> (r -> Free f a) -> s) -> s)
2022

23+
type FreeC f a = Free (Coyoneda f) a
24+
2125
class MonadFree f m where
2226
wrap :: forall a. f (m a) -> m a
2327

@@ -46,10 +50,16 @@ instance monadFreeFree :: (Functor f) => MonadFree f (Free f) where
4650
wrap = Free
4751

4852
liftF :: forall f m a. (Functor f, Monad m, MonadFree f m) => f a -> m a
49-
liftF fa = wrap $ return <$> fa
53+
liftF = wrap <<< (<$>) return
5054

5155
pureF :: forall f a. (Applicative f) => a -> Free f a
52-
pureF a = Free (pure (Pure a))
56+
pureF = Free <<< pure <<< Pure
57+
58+
liftFC :: forall f a. f a -> FreeC f a
59+
liftFC = liftF <<< liftCoyoneda
60+
61+
pureFC :: forall f a. (Applicative f) => a -> FreeC f a
62+
pureFC = liftFC <<< pure
5363

5464
-- Note: can blow the stack!
5565
iterM :: forall f m a. (Functor f, Monad m) => (forall a. f (m a) -> m a) -> Free f a -> m a
@@ -144,3 +154,10 @@ foreign import goEffImpl
144154

145155
goEff :: forall e f a. (Functor f) => (f (Free f a) -> Eff e (Free f a)) -> Free f a -> Eff e a
146156
goEff fn f = runFn6 goEffImpl resume isRight unsafeLeft unsafeRight fn f
157+
158+
-- Note: can blow the stack!
159+
goMC :: forall f m a. (Monad m) => Natural f m -> FreeC f a -> m a
160+
goMC nat = goM (liftCoyonedaTF nat)
161+
162+
goEffC :: forall e f a. Natural f (Eff e) -> FreeC f a -> Eff e a
163+
goEffC nat = goEff (liftCoyonedaTF nat)

src/Data/Coyoneda.purs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module Data.Coyoneda
22
( Coyoneda(..)
3+
, CoyonedaF(..)
34
, Natural(..)
45
, coyoneda
56
, liftCoyoneda

0 commit comments

Comments
 (0)