-
Notifications
You must be signed in to change notification settings - Fork 30
Open
Description
scanned currently consumes folds in a way that does not let them make use of the fact that they are always going to be applied to at least one element.
For example, attaching the maximum of all elements so far via scanned is slightly annoying. Most naturally, for s :: Stream (Of a) m r, one would use scanned like this
L.purely S.scanned L.maximum s :: Stream (Of (a, Maybe a)) m rThe Maybe here is misleading; all values are actually Just. One can rectify this via e.g. S.mapMaybe sequence, but it would be better to avoid this.
Concretely, one can generalize scanned like this:
scanned' :: Monad m => (a -> x) -> (x -> a -> x) -> (x -> b) -> Stream (Of a) m r -> Stream (Of (a, b)) m r
scanned' begin step done = loop Nothing
where
loop m stream =
case stream of
Return r -> return r
Effect mn -> Effect $ fmap (loop m) mn
Step (a :> rest) ->
case m of
Nothing -> do
let !x = begin a
!b = done x
S.yield (a, b)
loop (Just x) rest
Just x -> do
let !x' = step x a
!b = done x'
S.yield (a, b)
loop (Just x') restOne can easily define scanned in terms of scanned', namely
scanned step begin done = scanned' (const begin) step done In the example above, one can now write
L1.purely scanned' L1.maximum :: Stream (Of (a, a)) m rMetadata
Metadata
Assignees
Labels
No labels