[Haskell-cafe] concatMap with state for Data.Vector?
Evan Laforge
qdunkan at gmail.com
Fri Nov 8 03:01:55 UTC 2013
This is a Data.Vector question, hopefully here is a good place for
those. Or would it be better to ask on stackoverflow?
I want to generate a vector from another, where I interpolate between
each point. So I need something like concatMap because the vector
gets longer, but I need state because I need to remember the previous
value (and I need to look at the next value to avoid overrunning, but
that can be done with state and 'tails').
Stated imperatively, it would look like this:
state = Nothing
out = []
for (x, y) in signal:
case state of
Nothing -> out.append (x, y)
Just (x0, y0) -> for (x, y) in interpolate ...: out.append (x, y)
state = Just (x, y)
The simplest option would be just doing the transformation on a list:
`Vector.concat . snd . List.mapAccumL go Nothing . Vector.toList`
But unless fusion is more powerful than I imagined, that builds a
couple of lists and a bunch of intermediate vectors. I did try to
read the core, but it's hard to follow when vector is involved. If
they're large, it's probably no worse than a builder, but if they're
small, well I'd want a builder to fill up each chunk efficiently...
but there's no builder for Data.Vector (I did write one once, maybe I
should pull it out and dust it off).
unfoldr could also do it, but to emit multiple samples I'd need to
make the state `Either ([a], state) state`, and some awkward plumbing,
and constant tag checks.
So it's looking like converting to a list and back is the most
reasonable option... unless there's some way to express this that I'm
missing?
More information about the Haskell-Cafe
mailing list