如何改变STVector?

时间:2018-02-15 04:33:26

标签: haskell vector state mutable

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行更改为:< / p>

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’

1 个答案:

答案 0 :(得分:5)

你应该写得很好:

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

,并提供:

> verboseCopy
[1,2,4]
>

sort v执行排序作为对可变向量v的副作用,因此不需要&#34;保存&#34;或&#34;捕获&#34;排序结果,如果你担心的话。

您不需要明确键入v。 Haskell会推断它是一个可变向量,并将其作为IOVectorSTVector进行适当处理,具体取决于您是在IO或ST monad中使用它。

有关您的信息,您收到错误的原因是您提供的类型适用于v,但您已将其应用于thaw x有一个更复杂的类型。如果你写:

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

然后它会进行类型检查。然而,再次,这是不必要的,并且根本不会改变行为。 Haskell已经为你找到了这种类型。