我正在尝试编写一个动态STVector
,当超过矢量容量时,它将在ST monad
(对于命令式算法)内扩展。为此,我创建了一个包装 a 的新数据构造函数STVector
,并添加了一个Int
以跟踪最后插入的向量。问题是我从 typechecker 收到错误,因为我的状态实现似乎不正确。在下面的示例中,我将欣赏有关如何正确管理状态的指示DVec s
:
{-# LANGUAGE BangPatterns #-}
module Test where
import Data.Vector.Unboxed.Mutable as MU
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import GHC.Float.RealFracMethods (int2Float)
type MVI1 s = MVector (PrimState (ST s)) Int
data DVec s = DV {-# UNPACK #-}!Int -- this one keeps track of index of last vector
(MVI1 s)
append :: DVec s -> Int -> ST s (DVec s)
append (DV i v) x = do
if i < MU.length v then MU.unsafeWrite v i x >> return $ DV (i+1) v
else MU.unsafeGrow v (floor $ 1.5 * (int2Float $ MU.length v)) >>= (\y -> MU.unsafeWrite y i x >> return $ DV (i+1) y)
来自类型检查器的错误:
Couldn't match type `s' with `PrimState ((->) (DVec s))'
`s' is a rigid type variable bound by
the type signature for append :: DVec s -> Int -> ST s (DVec s)
at B.hs:11:11
Expected type: MVector (PrimState ((->) (DVec s))) Int
Actual type: MVI1 s
In the first argument of `unsafeWrite', namely `y'
In the first argument of `(>>)', namely `unsafeWrite y i x'
In the expression: unsafeWrite y i x >> return