-
Notifications
You must be signed in to change notification settings - Fork 11
Open
Description
foo, bar :: Stream (Of Char) [] Char
foo = lift ['a','b'] >>= lift . (: [])
bar = lift (['a','b'] >>= (: []))By the monad transformer laws, foo = bar, but in fact destroy foo P.show P.show P.show /= destroy bar P.show P.show P.show. I blame destroy. Indeed, Streaming.Internal.destroyExposed carefully documents the dangers and necessary restrictions, but destroy is (presumably accidentally) implemented using identical code:
destroy
:: (Functor f, Monad m) =>
Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b
destroy stream0 construct effect done = loop stream0 where
loop stream = case stream of
Return r -> done r
Effect m -> effect (liftM loop m)
Step fs -> construct (fmap loop fs)
destroyExposed stream0 construct effect done = loop stream0 where
loop stream = case stream of
Return r -> done r
Effect m -> effect (liftM loop m)
Step fs -> construct (fmap loop fs)The most obvious fix is to simply define
destroy = destroyExposed . unexposed
but there may be a slightly more efficient way.
Metadata
Metadata
Assignees
Labels
No labels