如何改变STVector?

How to mutate an STVector?

提问人:Jeffrey Benjamin Brown 提问时间:2/15/2018 更新时间:2/15/2018 访问量:481

问:

MVector有两种口味,和 .我想编写一些使用 的函数,以便尽管使用了 中的快速可变向量算法,但仍可以从纯代码调用它们。IOVectorSTVectorSTVectorData.Vector.Algorithms

在一个相关线程的帮助下,我已经走到了一半:我可以将一个不可变的上下文粘贴到一个可变的上下文中:VectorST

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.MutableSTVectorthawSTVectorthaw

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’
哈斯克尔 向量 可变

评论


答:

6赞 K. A. Buhr 2/15/2018 #1

你应该可以写:

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

给:

> verboseCopy
[1,2,4]
>

将排序作为对可变向量的副作用,因此无需“保存”或“捕获”排序结果,如果这是您担心的。sort vv

您无需显式键入 .Haskell 会将其推断为可变向量,并根据您是在 IO 还是 ST monad 中使用它来适当地将其视为 OR。vIOVectorSTVector

供您参考,出现错误的原因是您提供的类型是 ,但您已将其应用于具有更复杂类型的类型。如果你写:vthaw x

verboseCopy :: Vector Int
verboseCopy = runST $ do v <- thaw x :: ST s (STVector s Int)
                         sort v
                         freeze v

然后它会键入 check。但是,同样,这是不必要的,根本不会改变行为。Haskell已经为您弄清楚了这种类型。