Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.

Commit 5aee604

Browse files
committed
Copy Freer & iterFreer in.
1 parent 2430e16 commit 5aee604

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

src/Assigning/Assignment.hs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ import Prologue
9898
import Prelude hiding (fail)
9999
import qualified Assigning.Assignment.Table as Table
100100
import Control.Monad.Except (MonadError (..))
101-
import Control.Monad.Free.Freer
102101
import Data.AST
103102
import Data.Error
104103
import Data.Range
@@ -380,3 +379,56 @@ instance (Enum grammar, Eq1 ast, Ix grammar, Show grammar) => MonadError (Error
380379
Choose choices atEnd Nothing -> Tracing cs (Choose (fmap (>>= continue) choices) (fmap (>>= continue) atEnd) (Just handler)) `Then` pure
381380
Choose choices atEnd (Just onError) -> Tracing cs (Choose (fmap (>>= continue) choices) (fmap (>>= continue) atEnd) (Just (\ err -> (onError err >>= continue) <|> handler err))) `Then` pure
382381
_ -> Tracing cs assignment `Then` ((`catchError` handler) . continue)) (fmap pure rule)
382+
383+
384+
-- Freer
385+
386+
data Freer f a where
387+
Return :: a -> Freer f a
388+
Then :: f x -> (x -> Freer f a) -> Freer f a
389+
390+
infixl 1 `Then`
391+
392+
instance Functor (Freer f) where
393+
fmap f = go
394+
where go (Return result) = Return (f result)
395+
go (Then step yield) = Then step (go . yield)
396+
{-# INLINE go #-}
397+
{-# INLINE fmap #-}
398+
399+
instance Applicative (Freer f) where
400+
pure = Return
401+
{-# INLINE pure #-}
402+
403+
Return f <*> param = fmap f param
404+
Then action yield <*> param = Then action ((<*> param) . yield)
405+
{-# INLINE (<*>) #-}
406+
407+
Return _ *> a = a
408+
Then r f *> a = Then r ((*> a) . f)
409+
{-# INLINE (*>) #-}
410+
411+
Return a <* b = b *> Return a
412+
Then r f <* a = Then r ((<* a) . f)
413+
{-# INLINE (<*) #-}
414+
415+
instance Monad (Freer f) where
416+
return = pure
417+
{-# INLINE return #-}
418+
419+
Return a >>= f = f a
420+
Then r f >>= g = Then r (g <=< f)
421+
{-# INLINE (>>=) #-}
422+
423+
(>>) = (*>)
424+
{-# INLINE (>>) #-}
425+
426+
-- | Tear down a 'Freer' 'Monad' using iteration with an explicit continuation.
427+
--
428+
-- This is analogous to 'iter' with a continuation for the interior values, and is therefore suitable for defining interpreters for GADTs/types lacking a 'Functor' instance.
429+
iterFreer :: (forall x. (x -> a) -> f x -> a) -> Freer f a -> a
430+
iterFreer algebra = go
431+
where go (Return result) = result
432+
go (Then action continue) = algebra (go . continue) action
433+
{-# INLINE go #-}
434+
{-# INLINE iterFreer #-}

0 commit comments

Comments
 (0)