1
1
module Benchmark.Free0df59c5
2
- ( Free (..), GosubF ()
2
+ ( Free (..)
3
+ , GosubF
3
4
, FreeC (..)
4
- , MonadFree , wrap
5
- , Natural ()
6
- , liftF , liftFI , liftFC , liftFCI
7
- , pureF , pureFC
8
- , mapF , mapFC
9
- , bindF , bindFC
10
- , injF , injFC
5
+ , class MonadFree
6
+ , wrap
7
+ , Natural
8
+ , liftF
9
+ , liftFI
10
+ , liftFC
11
+ , liftFCI
12
+ , pureF
13
+ , pureFC
14
+ , mapF
15
+ , mapFC
16
+ , bindF
17
+ , bindFC
18
+ , injF
19
+ , injFC
11
20
, runFree
12
21
, runFreeM
13
22
, runFreeC
@@ -16,18 +25,15 @@ module Benchmark.Free0df59c5
16
25
17
26
import Prelude
18
27
19
- import Data.Exists
20
-
21
- import Control.Monad.Trans
22
- import Control.Monad.Eff
23
- import Control.Monad.Rec.Class
24
-
25
- import Data.Identity
26
- import Data.Coyoneda
27
- import Data.Either
28
- import Data.Function
29
- import Data.Maybe
30
- import Data.Inject (Inject , inj )
28
+ import Control.Monad.Rec.Class (class MonadRec , Step (..), tailRecM )
29
+ import Control.Monad.Trans.Class (class MonadTrans )
30
+ import Data.Coyoneda (Coyoneda , hoistCoyoneda , liftCoyoneda , lowerCoyoneda )
31
+ import Data.Either (Either (..), either )
32
+ import Data.Exists (Exists , mkExists , runExists )
33
+ import Data.Functor.Coproduct.Inject (class Inject , inj )
34
+ import Data.Identity (Identity (..))
35
+ import Data.Newtype (unwrap )
36
+ import Partial.Unsafe (unsafePartialBecause )
31
37
32
38
type Natural f g = forall a . f a -> g a
33
39
@@ -54,43 +60,43 @@ type FreeC f = Free (Coyoneda f)
54
60
class MonadFree f m where
55
61
wrap :: forall a . f (m a ) -> m a
56
62
57
- instance functorFree :: ( Functor f ) => Functor (Free f ) where
63
+ instance functorFree :: Functor f => Functor (Free f ) where
58
64
map f (Pure a) = Pure (f a)
59
65
map f g = liftA1 f g
60
66
61
- instance applyFree :: ( Functor f ) => Apply (Free f ) where
67
+ instance applyFree :: Functor f => Apply (Free f ) where
62
68
apply = ap
63
69
64
- instance applicativeFree :: ( Functor f ) => Applicative (Free f ) where
70
+ instance applicativeFree :: Functor f => Applicative (Free f ) where
65
71
pure = Pure
66
72
67
- instance bindFree :: ( Functor f ) => Bind (Free f ) where
73
+ instance bindFree :: Functor f => Bind (Free f ) where
68
74
bind (Gosub g) k = runExists (\(GosubF v) -> gosub v.a (\x -> gosub (\unit -> v.f x) k)) g
69
75
bind a k = gosub (\unit -> a) k
70
76
71
- instance monadFree :: ( Functor f ) => Monad (Free f )
77
+ instance monadFree :: Functor f => Monad (Free f )
72
78
73
79
instance monadTransFree :: MonadTrans Free where
74
80
lift f = Free $ do
75
81
a <- f
76
- return (Pure a)
82
+ pure (Pure a)
77
83
78
- instance monadFreeFree :: ( Functor f ) => MonadFree f (Free f ) where
84
+ instance monadFreeFree :: Functor f => MonadFree f (Free f ) where
79
85
wrap = Free
80
86
81
- instance monadRecFree :: ( Functor f ) => MonadRec (Free f ) where
87
+ instance monadRecFree :: Functor f => MonadRec (Free f ) where
82
88
tailRecM f u = f u >>= \o -> case o of
83
- Left a -> tailRecM f a
84
- Right b -> pure b
89
+ Loop a -> tailRecM f a
90
+ Done b -> pure b
85
91
86
92
-- | Lift an action described by the generating functor `f` into the monad `m`
87
93
-- | (usually `Free f`).
88
- liftF :: forall f m a . ( Functor f , Monad m , MonadFree f m ) => f a -> m a
94
+ liftF :: forall f m a . Functor f => Monad m => MonadFree f m => f a -> m a
89
95
liftF = wrap <<< map pure
90
96
91
97
-- | Lift an action described by the generating type constructor `f` into
92
98
-- | `Free g` using `Inject` to go from `f` to `g`.
93
- liftFI :: forall f g a . ( Inject f g , Functor g ) => f a -> Free g a
99
+ liftFI :: forall f g a . Inject f g => Functor g => f a -> Free g a
94
100
liftFI fa = liftF (inj fa :: g a )
95
101
96
102
-- | Lift an action described by the generating type constructor `f` into the monad
@@ -100,42 +106,42 @@ liftFC = liftF <<< liftCoyoneda
100
106
101
107
-- | Lift an action described by the generating type constructor `f` into
102
108
-- | `FreeC g` using `Inject` to go from `f` to `g`.
103
- liftFCI :: forall f g a . ( Inject f g ) => f a -> FreeC g a
109
+ liftFCI :: forall f g a . Inject f g => f a -> FreeC g a
104
110
liftFCI fa = liftFC (inj fa :: g a )
105
111
106
112
-- | An implementation of `pure` for the `Free` monad.
107
- pureF :: forall f a . ( Applicative f ) => a -> Free f a
113
+ pureF :: forall f a . Applicative f => a -> Free f a
108
114
pureF = Free <<< pure <<< Pure
109
115
110
116
-- | An implementation of `pure` for the `FreeC` monad.
111
- pureFC :: forall f a . ( Applicative f ) => a -> FreeC f a
117
+ pureFC :: forall f a . Applicative f => a -> FreeC f a
112
118
pureFC = liftFC <<< pure
113
119
114
120
-- | Use a natural transformation to change the generating functor of a `Free` monad.
115
- mapF :: forall f g a . ( Functor f , Functor g ) => Natural f g -> Free f a -> Free g a
121
+ mapF :: forall f g a . Functor f => Functor g => Natural f g -> Free f a -> Free g a
116
122
mapF t fa = either (\s -> Free <<< t $ mapF t <$> s) Pure (resume fa)
117
123
118
124
-- | Use a natural transformation to change the generating type constructor of
119
125
-- | a `FreeC` monad to another functor.
120
- mapFC :: forall f g a . ( Functor g ) => Natural f g -> FreeC f a -> Free g a
121
- mapFC t = mapF (liftCoyonedaTF t)
126
+ mapFC :: forall f g a . Functor g => Natural f g -> FreeC f a -> Free g a
127
+ mapFC t = mapF (lowerCoyoneda <<< hoistCoyoneda t)
122
128
123
129
-- | Use a natural transformation to interpret one `Free` monad as another.
124
- bindF :: forall f g a . ( Functor f , Functor g ) => Free f a -> Natural f (Free g ) -> Free g a
130
+ bindF :: forall f g a . Functor f => Functor g => Free f a -> Natural f (Free g ) -> Free g a
125
131
bindF fa t = either (\m -> t m >>= \fa' -> bindF fa' t) Pure (resume fa)
126
132
127
133
-- | Use a natural transformation to interpret a `FreeC` monad as a different
128
134
-- | `Free` monad.
129
- bindFC :: forall f g a . ( Functor g ) => FreeC f a -> Natural f (Free g ) -> Free g a
130
- bindFC fa t = bindF fa (liftCoyonedaTF t)
135
+ bindFC :: forall f g a . Functor g => FreeC f a -> Natural f (Free g ) -> Free g a
136
+ bindFC fa t = bindF fa (lowerCoyoneda <<< hoistCoyoneda t)
131
137
132
138
-- | Embed computations in one `Free` monad as computations in the `Free` monad for
133
139
-- | a coproduct type constructor.
134
140
-- |
135
141
-- | This construction allows us to write computations which are polymorphic in the
136
142
-- | particular `Free` monad we use, allowing us to extend the functionality of
137
143
-- | our monad later.
138
- injF :: forall f g a . ( Functor f , Functor g , Inject f g ) => Free f a -> Free g a
144
+ injF :: forall f g a . Functor f => Functor g => Inject f g => Free f a -> Free g a
139
145
injF = mapF inj
140
146
141
147
-- | Embed computations in one `FreeC` monad as computations in the `FreeC` monad for
@@ -144,18 +150,18 @@ injF = mapF inj
144
150
-- | This construction allows us to write computations which are polymorphic in the
145
151
-- | particular `Free` monad we use, allowing us to extend the functionality of
146
152
-- | our monad later.
147
- injFC :: forall f g a . ( Inject f g ) => FreeC f a -> FreeC g a
148
- injFC = mapF (liftCoyonedaT inj)
153
+ injFC :: forall f g a . Inject f g => FreeC f a -> FreeC g a
154
+ injFC = mapF (hoistCoyoneda inj)
149
155
150
- resume :: forall f a . ( Functor f ) => Free f a -> Either (f (Free f a )) a
156
+ resume :: forall f a . Functor f => Free f a -> Either (f (Free f a )) a
151
157
resume f = case f of
152
158
Pure x -> Right x
153
159
Free x -> Left x
154
- g -> case resumeGosub g of
160
+ g -> unsafePartialBecause " Existing implementation. " case resumeGosub g of
155
161
Left l -> Left l
156
162
Right r -> resume r
157
163
where
158
- resumeGosub :: Free f a -> Either (f (Free f a )) (Free f a )
164
+ resumeGosub :: Partial => Free f a -> Either (f (Free f a )) (Free f a )
159
165
resumeGosub (Gosub g) =
160
166
runExists (\(GosubF v) -> case v.a unit of
161
167
Pure a -> Right (v.f a)
@@ -164,23 +170,23 @@ resume f = case f of
164
170
165
171
-- | `runFree` runs a computation of type `Free f a`, using a function which unwraps a single layer of
166
172
-- | the functor `f` at a time.
167
- runFree :: forall f a . ( Functor f ) => (f (Free f a ) -> Free f a ) -> Free f a -> a
168
- runFree fn = runIdentity <<< runFreeM (Identity <<< fn)
173
+ runFree :: forall f a . Functor f => (f (Free f a ) -> Free f a ) -> Free f a -> a
174
+ runFree fn = unwrap <<< runFreeM (Identity <<< fn)
169
175
170
176
-- | `runFreeM` runs a compuation of type `Free f a` in any `Monad` which supports tail recursion.
171
177
-- | See the `MonadRec` type class for more details.
172
- runFreeM :: forall f m a . ( Functor f , MonadRec m ) => (f (Free f a ) -> m (Free f a )) -> Free f a -> m a
178
+ runFreeM :: forall f m a . Functor f => MonadRec m => (f (Free f a ) -> m (Free f a )) -> Free f a -> m a
173
179
runFreeM fn = tailRecM \f ->
174
180
case resume f of
175
- Left fs -> Left <$> fn fs
176
- Right a -> return ( Right a)
181
+ Left fs -> Loop <$> fn fs
182
+ Right a -> pure ( Done a)
177
183
178
184
-- | `runFreeC` is the equivalent of `runFree` for type constructors transformed with `Coyoneda`,
179
185
-- | hence we have no requirement that `f` be a `Functor`.
180
- runFreeC :: forall f a . (forall a . f a -> a ) -> FreeC f a -> a
181
- runFreeC nat = runIdentity <<< runFreeCM (Identity <<< nat)
186
+ runFreeC :: forall f a . (forall b . f b -> b ) -> FreeC f a -> a
187
+ runFreeC nat = unwrap <<< runFreeCM (Identity <<< nat)
182
188
183
189
-- | `runFreeCM` is the equivalent of `runFreeM` for type constructors transformed with `Coyoneda`,
184
190
-- | hence we have no requirement that `f` be a `Functor`.
185
191
runFreeCM :: forall f m a . (MonadRec m ) => Natural f m -> FreeC f a -> m a
186
- runFreeCM nat = runFreeM (liftCoyonedaTF nat)
192
+ runFreeCM nat = runFreeM (lowerCoyoneda <<< hoistCoyoneda nat)
0 commit comments