Jus*_* L. 10 haskell typeclass type-signature io-monad st-monad
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 ()
Run Code Online (Sandbox Code Playgroud)
现在我可以使用这些 -
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
Run Code Online (Sandbox Code Playgroud)
但是这里发生了什么?什么是PrimMonad
?是PrimState
一个构造函数?
我知道这里有一些绑定,在PrimMonad
类monad上.thaw
返回m (MVector (PrimState m) a)
,哪里m
是PrimMonad
......但monad包含自己?为什么m
在另一个的背景下m
呢?
我看到一切基本上都与此有关,PrimState
或者PrimMonad
我看不出这与可变/可存储的向量有什么关系.那些允许它们存储状态的类型类有什么特别之处吗?
感谢您的时间!
Chr*_*icz 15
我认为你正在使用矢量包,如
import Data.Vector.Mutable
Run Code Online (Sandbox Code Playgroud)
继PrimMonad
类型类导致低级别的细节; 需要注意的是两个实例:
instance PrimMonad IO where ...
instance PrimMonad (ST s) where ...
Run Code Online (Sandbox Code Playgroud)
所以(PrimMonad m)
只是一种说法m
是IO
或者(ST s)
.这些是Haskell设置为允许你改变内存的两个基本monad.要清楚,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
Run Code Online (Sandbox Code Playgroud)
(PrimState m)
代码中的类型取决于(PrimMonad m)
分配给它的实例.
instance PrimMonad IO where
type PrimState IO = RealWorld
instance PrimMonad (ST s) where
type PrimState (ST s) = s
Run Code Online (Sandbox Code Playgroud)
该RealWorld
类型是GHC中IO的低级内部实现细节.s
附加的类型(ST s)
是存在类型的技巧,可以runST
证明没有任何可变的东西逃脱了(ST s)
monad.
要使相同的代码工作,IO
并(ST s)
使用PrimMonad
类型类(与关联PrimState
)来提供临时重载.
归档时间: |
|
查看次数: |
767 次 |
最近记录: |