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).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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With