haskell / haskell/vector

Discussion: High-level functions that can convert between vector types

Open
#373 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
400
Forks
145
PR merge metrics
No merged PRs in 30d

Description

**Edit:** Issue description of the underlying problem https://github.com/haskell/vector/issues/373#issuecomment-808821411

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:

```haskell
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`](https://hackage.haskell.org/package/vector-0.12.2.0/docs/Data-Vector-Generic.html#v:map) with [`convert`](https://hackage.haskell.org/package/vector-0.12.2.0/docs/Data-Vector-Generic.html#v:convert), of type:

```haskell
convertingMap :: (Vector v a, Vector w b) => (a -> b) -> v a -> w b
```

**Edit:** Solution for this specific function due to @lehins in https://github.com/haskell/vector/issues/373#issuecomment-808820750.

---

Alternatives considered:

* `convertingMap vals f = VG.map f (VG.convert vals)` or `VG.convert (VG.map f vals)` isn't great, because it requires that `v` and `w` can store the same elements, which sometimes isn't the case, e.g. I can have a data `D1` that only works with `Unboxed` and data `D2` that only works with `Storable`.
* I currently use:
```haskell
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)
```
but I don't know if that's optimal stream-fusion-wise.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.