【问题标题】:Writing chained mutation/modification functions for Mutable Vectors为可变向量编写链式突变/修改函数
【发布时间】:2013-06-29 06:27:33
【问题描述】:

所以我想创建一个与

工作方式相同的方法
import Data.Vector as V
import Data.Vector.Mutable as MV
import Control.Monad.ST

type DoubleVec = V.Vector Double

incrAndSwap :: DoubleVec -> Int -> Int -> Int -> DoubleVec
incrAndSwap vec i a b = runST $ do
  mvec <- V.thaw vec
  oldval <- MV.read mvec i                          -- 1
  MV.write mvec i (val + 1)                         -- 2
  MV.swap mvec a b
  V.freeze mvec

但是能够将两条标记的行“浓缩”成一个函数,并且能够说:

incrAndSwap :: DoubleVec -> Int -> Int -> Int -> DoubleVec
incrAndSwap vec i a b = runST $ do
  mvec <- V.thaw vec
  incrAt mvec i
  MV.swap mvec a b
  V.freeze mvec

基本上,写那个incrAt i函数。

我尝试复制MV.write 的类型签名,但我无法使用类型签名得到任何东西;没有编译。

这是我最近的尝试

import Control.Monad.Primitive

type MDoubleVec s = MV.STVector s Double

incrAt :: (PrimMonad m) => MDoubleVec (PrimState m) -> Int -> m ()
incrAt mvec i = MV.write mvec i (val + 1)
  where
    val = MV.read mvec i          -- val is stuck in monad m0

但我不知道如何将 val 从 monad m0 中取出——显然,根据编译器的说法,它就在其中。这是有道理的。

有人知道我该怎么做吗?

【问题讨论】:

    标签: haskell monads


    【解决方案1】:

    您需要在m monad 中执行MV.read,并将其结果绑定到val。基本上,只需将原始代码的两行逐字移动即可:

    incrAt :: (PrimMonad m) => MDoubleVec (PrimState m) -> Int -> m ()
    incrAt path i = do
        val <- MV.read path i
        MV.write path i (val + 1)
    

    顺便说一句,仅供参考,类型错误提到m0 而不是m(起初可能会令人困惑)的原因是,在您的代码中,没有任何东西可以链接val 所在的monad定义到你做MV.read的monad。但真正的问题是 MV.read 是一元的,所以你需要绑定它的结果才能在也是一元的 MV.write 中使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 2022-01-19
      • 2015-03-01
      • 2017-01-06
      相关资源
      最近更新 更多