raise and writer effect

This commit is contained in:
Sandy Maguire 2019-03-20 20:02:43 -04:00
parent 4b2d907c22
commit ecd1f5f5a2
2 changed files with 67 additions and 0 deletions

View File

@ -10,6 +10,7 @@ module Polysemy
, sendM
, run
, runM
, raise
, Lift ()
, usingSemantic
, liftSemantic
@ -20,6 +21,7 @@ import Control.Monad.Fix
import Control.Monad.IO.Class
import Data.Functor.Identity
import Polysemy.Lift
import Polysemy.Effect
import Polysemy.Union
@ -88,6 +90,16 @@ hoistSemantic nat (Semantic m) = Semantic $ \k -> m $ \u -> k $ nat u
{-# INLINE hoistSemantic #-}
raise :: Semantic r a -> Semantic (e ': r) a
raise = hoistSemantic $ hoist raise' . weaken
{-# INLINE raise #-}
raise' :: Semantic r a -> Semantic (e ': r) a
raise' = raise
{-# NOINLINE raise' #-}
send :: Member e r => e (Semantic r) a -> Semantic r a
send = liftSemantic . inj
{-# INLINE[3] send #-}

55
src/Polysemy/Writer.hs Normal file
View File

@ -0,0 +1,55 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE TemplateHaskell #-}
module Polysemy.Writer where
import Polysemy
import Polysemy.Effect.New
import Polysemy.State
data Writer o m a
= Tell o a
| x. Listen (m x) (o -> x -> a)
| x. Censor (o -> o) (m x) (x -> a)
deriving instance Functor (Writer o m)
instance Effect (Writer o) where
weave s _ (Tell o k) = Tell o $ k <$ s
weave s distrib (Listen m k) =
Listen (distrib $ m <$ s) (fmap fmap k)
weave s distrib (Censor f m k) =
Censor f (distrib $ m <$ s) (fmap k)
{-# INLINE weave #-}
hoist = defaultHoist
{-# INLINE hoist #-}
makeSemantic ''Writer
runWriter
:: Monoid o
=> Semantic (Writer o ': r) a
-> Semantic r (o, a)
runWriter = runState mempty . reinterpret \case
Tell o k -> do
modify (<> o)
pure k
Listen m k -> do
(o, a) <- raise $ runWriter' m
pure $ k o a
Censor f m k -> do
(o, a) <- raise $ runWriter' m
modify (<> f o)
pure $ k a
{-# INLINE runWriter #-}
runWriter'
:: Monoid o
=> Semantic (Writer o ': r) a
-> Semantic r (o, a)
runWriter' = runWriter
{-# NOINLINE runWriter' #-}