@@ -35,10 +35,7 @@ tell w1 = do
35 IdE (Writer v) <- getEffect
35 IdE (Writer v) <- getEffect
36 unsafeEff_ . modifyMVar_ v $ \w0 -> let w = w0 <> w1 in w `seq` pure w
36 unsafeEff_ . modifyMVar_ v $ \w0 -> let w = w0 <> w1 in w `seq` pure w
39− :: forall w es a. (Writer w :> es, Monoid w)
38+listen :: (Writer w :> es, Monoid w) => Eff es a -> Eff es (a, w)
42listen m = unsafeEff $ \es -> uninterruptibleMask $ \restore -> do
39listen m = unsafeEff $ \es -> uninterruptibleMask $ \restore -> do
43 v1 <- newMVar mempty
40 v1 <- newMVar mempty
44 -- Replace thread local MVar with a fresh one for isolated listening.
41 -- Replace thread local MVar with a fresh one for isolated listening.
@@ -49,18 +46,14 @@ listen m = unsafeEff $ \es -> uninterruptibleMask $ \restore -> do
49 -- Merge results accumulated in the local MVar with the mainline. If an
46 -- Merge results accumulated in the local MVar with the mainline. If an
50 -- exception was received while listening, merge results recorded so far.
47 -- exception was received while listening, merge results recorded so far.
51 merge es v0 v1 = do
48 merge es v0 v1 = do
52− unsafePutEnv @(Writer w) (IdE (Writer v0)) es
49+ unsafePutEnv (IdE (Writer v0)) es
53 w1 <- readMVar v1
50 w1 <- readMVar v1
54 -- The mask is uninterruptible because modifyMVar_ v0 might block and if
51 -- The mask is uninterruptible because modifyMVar_ v0 might block and if
55 -- we get an async exception while waiting, w1 will be lost.
52 -- we get an async exception while waiting, w1 will be lost.
56 modifyMVar_ v0 $ \w0 -> let w = w0 <> w1 in w `seq` pure w
53 modifyMVar_ v0 $ \w0 -> let w = w0 <> w1 in w `seq` pure w
60− :: (Writer w :> es, Monoid w)
56+listens :: (Writer w :> es, Monoid w) => (w -> b) -> Eff es a -> Eff es (a, b)
64listens f m = do
57listens f m = do
65 (a, w) <- listen m
58 (a, w) <- listen m
66 pure (a, f w)
59 pure (a, f w)