此类型签名是怎么回事?(Vector.Mutable 修饰符在 Haskell 中)



Haskell中的可变载体有三个元素级突变子:

read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
write :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
swap :: PrimMonad m => MVector (PrimState m) a -> Int -> Int -> m ()

现在我可以使用这些精细的

import Data.Vector
import Data.Vector.Mutable 
import Control.Monad.ST
import Control.Monad.Primitive 
incrAt :: Vector Double -> Int -> Vector Double
incrAt vec i = runST $ do
  mvec <- thaw vec
  oldval <- read mvec i
  write mvec i (oldval + 1)
  freeze mvec

但是这里发生了什么?什么是PrimMonadPrimState是构造函数吗?

我知道这里有一些绑定,在PrimMonad类monad上。thaw返回m (MVector (PrimState m) a),其中mPrimMonad。。。但是monad包含它自己?为什么m在另一个m的上下文中?

我看到所有东西基本上都绑定在这个PrimStatePrimMonad上,但我不明白这与可变/可存储向量有什么关系。这些类型类有什么特别的地方可以存储状态吗?

感谢您抽出时间!

我认为您使用的是矢量包,如

import Data.Vector.Mutable

遵循PrimMonad类型类会导致低级别的详细信息;需要注意的是以下两个例子:

instance PrimMonad IO where ...
instance PrimMonad (ST s) where ...

所以(PrimMonad m)只是说mIO(ST s)的一种方式。这是两个基本的monad,Haskell在其中被设置为允许您改变内存。需要明确的是,m是一个类型构造函数,将m应用于类似Int的类型会得到一个类型:m Int

需要强调的是:IO(ST s)是特别的,因为它们允许您使用这种能力来"存储状态",从而改变实际内存。它们以Haskell的其他部分隐藏的原始形式公开了这种功能。

现在PrimState是一个新事物:一个关联的数据类型。在PrimMonad类型类中有一个声明:

-- | Class of primitive state-transformer monads
class Monad m => PrimMonad m where
  -- | State token type
  type PrimState m

(PrimState m)在代码中的类型取决于分配给它的(PrimMonad m)的实例

instance PrimMonad IO where
  type PrimState IO = RealWorld
instance PrimMonad (ST s) where
  type PrimState (ST s) = s

RealWorld类型是GHC中IO的低级别内部实现细节。附加到(ST s)s类型是存在类型技巧,它让runST证明没有任何可变的东西逃脱了(ST s) monad。

为了使相同的代码在IO(ST s)中工作,PrimMonad类型类(具有相关联的PrimState)用于提供自组织重载。

最新更新