3
我有一个简单的就地函数,我正在使用可变向量来实现。然而,这个函数需要一个最容易使用不变矢量构建的向量。下面是一些玩具代码演示基本结构(但可能不会编译):在可变函数中获取不可变向量的类型
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
我没有看到任何方式f
确定(有效的)不变载体类型v
。我只想让myvec
生成一个多态的可变的向量类型,但即使对于上面的简单函数,myvec
的代码也更加丑陋。
我正在寻找一个解决方案,让我
- 轻松定义
myvec
(如上定义)(和我没有看到任何方式与可变矢量干净做到这一点) - 用途可能的最具体的矢量类型:例如,一种解决方案是使
myvec
返回一个盒装矢量,它可以容纳任何r
类型。但是,我们担心速度,因此如果f
的输入是可变的无框矢量,myvec
应该是可变的无框矢量或不可变的无框矢量。 - 我也想避免
myvec
通过从main
(其中不变的类型是已知的):我们有足够的信息f
生成本地值,所以经过矢量从main
是没有必要的(除可能用于类型信息)。
你不能传入类型吗? 'f(undefined :: Int)v''?还是有一些GADT可以用来代替Vector类?我不是这方面的专家;只是猜测它。 – dfeuer
我可以将不可变的向量类型从'main'传递给''f'(不确定你在哪里用'undefined :: Int'),但是看起来很疯狂,我应该在完全有效的时候这样做丑陋的)替代方案是把'myvec'写成一个可变的函数。 – crockeea
你想让'myvec'生成的向量被填充到什么地方?如果它将是不可改变的,你需要在创作时知道。目前你已经得到它生成一个'Int'索引的向量。 – rampion