Description
Edit: Issue description of the underlying problem #373 (comment)
Below is the original question that led to it:
I often work with indices that I'd like to store in Unboxed.Vector Int
vectors, and Generic.Vector vector a
vectors into which those indices point.
At some point I have to resolve the indices back into the original generic vector type. I would like to do:
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Unboxed as VU
myIndexVector :: VU.Vector Int
atIndices :: (VG.Vector vector a) => vector a -> VU.Vector Int -> vector a
atIndices vals indices = VG.map (vals VG.!) indices
(This is basically the same as myVector[indicesVector]
does in Python's numpy
.)
However in the above, VG.map (xs VG.!) indices
does not typecheck, beause map
requires that the input vector type be the same as the output vector type.
Thus it would be awesome to have a convertingMap
function that combines map
with convert
, of type:
convertingMap :: (Vector v a, Vector w b) => (a -> b) -> v a -> w b
Edit: Solution for this specific function due to @lehins in #373 (comment).
Alternatives considered:
convertingMap vals f = VG.map f (VG.convert vals)
orVG.convert (VG.map f vals)
isn't great, because it requires thatv
andw
can store the same elements, which sometimes isn't the case, e.g. I can have a dataD1
that only works withUnboxed
and dataD2
that only works withStorable
.- I currently use:
but I don't know if that's optimal stream-fusion-wise.
convertingVectorMap :: (VG.Vector vectorA a, VG.Vector vectorB b) => (a -> b) -> vectorA a -> vectorB b convertingVectorMap f va = VG.generate (VG.length va) $ \i -> f (va VG.! i)