MVector 有两种形式,IOVectorSTVector。我想编写一些使用 STVector 的函数,这样尽管在 Data.Vector.Algorithms 中使用了快速可变向量算法,它们也可以从纯代码中调用。

a related thread 的帮助下,我已经做到了:我可以将不可变的 Vector 粘贴到可变的 ST 上下文中:

import Control.Monad.ST
import Data.Vector
import Data.Vector.Algorithms.Intro (sort)

x = fromList [1,4,2] :: Vector Int

verboseCopy :: Vector Int
verboseCopy = runST $ do v <- thaw x
                         freeze v

我只需要在解冻和卡住之间运行 sort

也许令人惊讶的是,我不必 import Data.Vector.Mutable ,这是 STVector 定义的地方。也许我应该使用类型签名来指定我希望 thaw 生成一个 STVector ,但我不知道如何:如果我将 thaw 行更改为:
v <- thaw x :: Data.Vector.Mutable.STVector s Int

我收到此错误:
• Couldn't match expected type ‘MVector
                                  (primitive-0.6.3.0:Control.Monad.Primitive.PrimState (ST s))
                                  Int’
              with actual type ‘Int’
• In the first argument of ‘freeze’, namely ‘v’

最佳答案

你应该没问题写:

verboseCopy :: Vector Int
verboseCopy = runST $ do v <- thaw x
                         sort v
                         freeze v

给予:
> verboseCopy
[1,2,4]
>
sort v 将排序作为对可变向量 v 的副作用执行,因此如果您担心的话,则无需“保存”或“捕获”排序结果。

您不需要显式键入 v 。 Haskell 会推断它是一个可变向量,并将根据您是在 IO 还是 ST monad 中使用它来适本地将其视为 IOVectorSTVector

对于您的信息,您收到错误的原因是您提供的类型适用于 v ,但您已将其应用于具有更复杂类型的 thaw x 。如果你写:
verboseCopy :: Vector Int
verboseCopy = runST $ do v <- thaw x :: ST s (STVector s Int)
                         sort v
                         freeze v

然后它会输入检查。然而,这又是不必要的,根本不会改变行为。 Haskell 已经为你找到了这种类型。

关于haskell - 如何改变 STVector?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48799997/

10-12 14:24