-
Notifications
You must be signed in to change notification settings - Fork 0
/
Writer.hs
59 lines (48 loc) · 1.22 KB
/
Writer.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{-|
The `MTL.WriterMonad`-like effect.
I can't guarantee that if you route implementation via `Data.IORef.IORef` it will
hold any properties if used in parallel processes.
-}
module Effect.Writer
( -- * Interface
Writer
, tell
, listen
-- * Implementation
, writerToState
-- * Re-exporting core
, module Core
)
where
import Core
import Effect.Final
import Effect.State
import Data.IORef ()
-- | Ability to output messages.
data Writer w m a where
Say :: w -> Writer w m ()
Intercept :: m a -> Writer w m (w, a)
instance Effect (Writer w) where
weave f (Say w) = Say w
weave f (Intercept ma) = Intercept (f ma)
-- | Output a message.
tell :: forall w fs. Members '[Writer w] fs => w -> Eff fs ()
tell w = send (Say w)
-- | Intercept the messages the action sends.
listen :: forall w fs a. Members '[Writer w] fs => Eff fs a -> Eff fs (w, a)
listen act = send (Intercept act)
-- | Implement as `State`.
writerToState
:: forall w fs
. (Members '[State w] fs, Monoid w)
=> Eff (Writer w : fs)
~> Eff fs
writerToState = plug \case
Say w -> modify (w <>)
Intercept ma -> do
old <- get @w
put @w mempty
res <- ma
new <- get
modify (old <>)
return (new, res)