Skip to content

Commit de660a5

Browse files
authored
Merge pull request #52 from natefaubion/free-resume
Add `resume`.
2 parents 431cb8c + 08dcf47 commit de660a5

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/Control/Monad/Free.purs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Control.Monad.Free
88
, foldFree
99
, runFree
1010
, runFreeM
11+
, resume
1112
) where
1213

1314
import Prelude
@@ -17,7 +18,6 @@ import Control.Monad.Trans (class MonadTrans)
1718

1819
import Data.CatList (CatList, empty, snoc, uncons)
1920
import Data.Either (Either(..), either)
20-
import Data.Identity (Identity(..), runIdentity)
2121
import Data.Inject (class Inject, inj)
2222
import Data.Maybe (Maybe(..))
2323
import Data.Tuple (Tuple(..))
@@ -115,7 +115,12 @@ foldFree k = tailRecM go
115115
-- | Run a free monad with a function that unwraps a single layer of the functor
116116
-- | `f` at a time.
117117
runFree :: forall f a. Functor f => (f (Free f a) -> Free f a) -> Free f a -> a
118-
runFree k = runIdentity <<< runFreeM (Identity <<< k)
118+
runFree k = go
119+
where
120+
go :: Free f a -> a
121+
go f = case toView f of
122+
Return a -> a
123+
Bind g i -> go (k (i <$> g))
119124

120125
-- | Run a free monad with a function mapping a functor `f` to a tail-recursive
121126
-- | monad `m`. See the `MonadRec` type class for more details.
@@ -132,6 +137,16 @@ runFreeM k = tailRecM go
132137
Return a -> Right <$> pure a
133138
Bind g i -> Left <$> k (i <$> g)
134139

140+
-- | Unwraps a single layer of the functor `f`.
141+
resume
142+
:: forall f a
143+
. Functor f
144+
=> Free f a
145+
-> Either (f (Free f a)) a
146+
resume f = case toView f of
147+
Return a -> Right a
148+
Bind g i -> Left (i <$> g)
149+
135150
fromView :: forall f a. FreeView f a Val -> Free f a
136151
fromView f = Free (unsafeCoerceFreeView f) empty
137152
where

0 commit comments

Comments
 (0)