MVector
有两种形式,IOVector
和 STVector
。我想编写一些使用 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 中使用它来适本地将其视为 IOVector
或 STVector
。对于您的信息,您收到错误的原因是您提供的类型适用于
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/