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
行更改为:< / 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’
答案 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会推断它是一个可变向量,并将其作为IOVector
或STVector
进行适当处理,具体取决于您是在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已经为你找到了这种类型。