Reputation: 21811
I have a simple in-place function which I'm using mutable vectors to implement. However, this function needs a vector which is most easily constructed using an immutable vector. Below is some toy code demonstrating the basic structure (but probably does not compile):
import Data.Vector.Generic as V
import Data.Vector.Unboxed as U
myvec :: (Vector v r) => Int -> v r
myvec i = V.generate i id
f :: (MVector v r, PrimMonad m) => v (PrimState m) r -> m ()
f y = let v = myvec 10 -- what should the type of `v` be?
--the following doesn't work since the Mutable type family is not injective:
_ = return v `asTypeOf` unsafeFreeze y
in do ....
main = do
-- at the top level, I know the input can be unboxed
let v = U.generate 10 (+(1::Int))
v' <- thaw v
f v'
y <- freeze v'
print y
I don't see any way for f
to determine a (valid) immutable vector type for v
. I would just make myvec
generate a polymorphic mutable vector type, but even for the simple function above, the code for myvec
is much uglier.
I'm looking for a solution that allows me to
myvec
(as defined above) (and I don't see any way to do this cleanly with mutable vectors)myvec
return a boxed vector, which can hold any r
type. However, we are concerned about speed so if the input to f
is a mutable unboxed vector, myvec
should either be a mutable unboxed vector or a immutable unboxed vector.myvec
from main
(where the immutable type is known): we have enough information to generate the values locally in f
, so passing the vector from main
isn't necessary (except possibly for type information).Upvotes: 3
Views: 344
Reputation: 21811
After some digging around, I figured out how to write a mutable generate
function:
import Data.Vector.Generic.Mutable as M
import Data.Vector.Fusion.Stream as S
import Control.Monad.Primitive
mutableGenerate :: (MVector v r, PrimMonad m) => Int -> (Int -> r) -> m (v (PrimState m) r)
mutableGenerate i f = M.unstream $ S.generate i f
This allows me to generate a polymorphic mutable vector, but with concise notation of an immutable vector. This seems to me like a useful function that should be included in Data.Vector.Generic.Mutable
.
Upvotes: 1