[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