Skip to content

Commit 77f6d96

Browse files
authored
Merge pull request #54 from natefaubion/subst-free
Add substFree
2 parents de660a5 + 489144b commit 77f6d96

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/Control/Monad/Free.purs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module Control.Monad.Free
66
, hoistFree
77
, injF
88
, foldFree
9+
, substFree
910
, runFree
1011
, runFreeM
1112
, resume
@@ -90,7 +91,7 @@ suspendF f = fromView (Bind (unsafeCoerceF (pure f)) unsafeCoerceVal)
9091
-- | Use a natural transformation to change the generating type constructor of a
9192
-- | free monad.
9293
hoistFree :: forall f g. (f ~> g) -> Free f ~> Free g
93-
hoistFree k = foldFree (liftF <<< k)
94+
hoistFree k = substFree (liftF <<< k)
9495

9596
-- | Embed computations in one `Free` monad as computations in the `Free` monad
9697
-- | for a coproduct type constructor.
@@ -112,6 +113,16 @@ foldFree k = tailRecM go
112113
Return a -> Right <$> pure a
113114
Bind g i -> (Left <<< i) <$> k g
114115

116+
-- | Like `foldFree`, but for folding into some other Free monad without the
117+
-- | overhead that `MonadRec` incurs.
118+
substFree :: forall f g. (f ~> Free g) -> Free f ~> Free g
119+
substFree k = go
120+
where
121+
go :: Free f ~> Free g
122+
go f = case toView f of
123+
Return a -> pure a
124+
Bind g i -> k g >>= go <$> i
125+
115126
-- | Run a free monad with a function that unwraps a single layer of the functor
116127
-- | `f` at a time.
117128
runFree :: forall f a. Functor f => (f (Free f a) -> Free f a) -> Free f a -> a

0 commit comments

Comments
 (0)