Open
Description
The current definitions of listen
and pass
are:
instance (Monoid w, HasState tag w m)
=> HasWriter tag w (WriterLog m)
where
writer_ tag (a, w) = yield_ tag w >> pure a
{-# INLINE writer_ #-}
listen_ :: forall a. Proxy# tag -> WriterLog m a -> WriterLog m (a, w)
listen_ _ m = coerce @(m (a, w)) $ do
w0 <- get @tag
put @tag mempty
a <- coerce m
w <- get @tag
put @tag $! w0 <> w
pure (a, w)
{-# INLINE listen_ #-}
pass_ :: forall a. Proxy# tag -> WriterLog m (a, w -> w) -> WriterLog m a
pass_ _ m = coerce @(m a) $ do
w0 <- get @tag
put @tag mempty
(a, f) <- coerce @_ @(m (a, w -> w)) m
w <- get @tag
put @tag $! w0 <> f w
pure a
{-# INLINE pass_ #-}
There is no error recovery at all, and by temporarily "repurposing" the mutable state, other threads end up not writing to where they should be writing.
The concurrency problem may not be worth fixing (in some sense), but at least it deserves a warning in the docs; having no error recovery is arguably a larger problem.
Metadata
Metadata
Assignees
Labels
No labels