-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Description
The Queue type is currently a bit of a mess, in that it doesn't have quite the right amortized bounds. In particular, if someone does something like
q = ((((s <> Empty) <> Empty) <|> Empty) <|> Empty) <|> Emptyand then evaluates viewl q in multiple futures, each of those futures will walk the Emptys to discard them.
We can't give it the right bounds without breaking laziness, a problem which has bitten us rather badly before.
What we can do is replace the catenable queues with lazy catenable non-empty queues. These don't seem to suffer from that problem, so they form a nice clean ADT to built atop. There are a couple pain points:
viewlends up with a different type, which doesn't match the sequence class we currently use. Not a big deal.linkAllmay get a bit more complicated. I don't know how bad it'll look.- We'll have to define
empty :: SeqT adifferently. Specifically, we'll need to writewhereempty = SeqT (singleton (pure Empty))
Emptyhere is the emptyViewT. This will generally be less efficient to handle than a dedicatedEmptyconstructor in cases where a computation does nothing other than fail. For example, if someone writesm <|> (if x then empty else ...) <|> nthen currently we can immediately skip over theEmptywhen we reach it. With the simplified version, we'll end up with a separateemptyfor each underlying monad, which contains a (trivial) computation we must "run" to figure out that there's nothing to do. I'm guessing the theoretical cleanliness isn't worth the performance impact, but it depends on the code people want to write.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels