这个类型签名发生了什么? (Haskell 中的 Vector.Mutable 修饰符)

2024-01-06

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

但这是怎么回事?什么是PrimMonad?并且是PrimState构造函数?

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

我看到一切基本上都与此有关PrimState or PrimMonad,但我不明白这与可变/可存储向量有什么关系。这些允许它们存储状态的类型类有什么特别之处吗?

感谢您的时间!


我认为你正在使用矢量包 http://hackage.haskell.org/packages/archive/vector/0.10.0.1/doc/html/Data-Vector-Mutable.html, as in

import Data.Vector.Mutable

PrimMonad类型类导致低级细节;需要注意的是两个实例:

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

So (PrimMonad m)只是一种说法m或者是IO or (ST s)。这是 Haskell 设置的两个基本 monad,可以让你改变内存。需要明确的是,m是一个类型构造函数并应用m像这样的类型Int给出一个类型:m Int.

强调一下:IO and (ST s)很特别,因为它们允许您使用这种改变实际内存的能力来“存储状态”。他们以 Haskell 其余部分隐藏的原始形式公开了此功能。

现在 PrimState 是一个新事物:关联数据类型 http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl。在里面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

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

为了使相同的代码工作IO and (ST s) the PrimMonad类型类(带有关联的PrimState) 用于提供临时重载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这个类型签名发生了什么? (Haskell 中的 Vector.Mutable 修饰符) 的相关文章

随机推荐