haskell - 在另一个数据构造函数中写入 STVector

标签 haskell vector

我正在尝试编写一个动态STVector,当超出向量容量时,它将在ST monad(用于命令式算法)中扩展。为此,我创建了一个包装 STVector 的新数据构造函数,并添加一个 Int 来跟踪最后插入的向量。问题是我从类型检查器中收到错误,因为我的状态实现似乎不正确。我将感谢以下示例中有关如何正确管理 DVec 的状态的指示:

{-# 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

最佳答案

问题是 $ 运算符的优先级最低,因此它左边的所有内容都被视为一个函数。 使用 return (DV (i+1) v) 而不是 return $ DV (i+1) v

我是怎么发现这个问题的?

我删除了您的类型注释,以查看 ghci 将确定什么类型。 Ghci 检测到具有此约束的类型 (Control.Monad.Primitive.PrimMonad ((->) (DVec (PrimState m)))。这意味着存在一些错误,使 ghci 认为 <使用的 code>PrimMonad 也是一个函数。很明显 ($) 就是其背后的原因。

关于haskell - 在另一个数据构造函数中写入 STVector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16885873/

相关文章:

parsing - Haskell parsec 给出 <<loop>> 错误

c++ - 为 vector 重载 "+,-,*"运算符时出现问题 - "no match for operator..."

haskell - Yesod 条件子网站

c++ - 通过 char 将 .txt 读入 vector 但不忽略空格

algorithm - 为什么向量数组加倍?

c++ - Bjarne Stroustrup Book - vector 和 For 循环 - 不起作用

c++ - 结合 std::string 和 std::vector<char>

haskell - 在镜头库中使用Traversable []和Applicative Maybe的效果

parsing - haskell : Recursive datatype - parse [String] to n-ary tree

haskell - ByteString 采用 ISO-8859-1?