【发布时间】:2013-08-01 14:36:38
【问题描述】:
Data.Vector.Mutable 似乎需要ST s 和IO monad 中的PrimMonad 实例。
类型类被定义为这样--
-- | Class of primitive state-transformer monads
class Monad m => PrimMonad m where
-- | State token type
type PrimState m
-- | Execute a primitive operation
primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
-- | Expose the internal structure of the monad
internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)
它们是这样实现的--
instance PrimMonad IO where
type PrimState IO = RealWorld
primitive = IO
internal (IO p) = p
instance PrimMonad (ST s) where
type PrimState (ST s) = s
primitive = ST
internal (ST p) = p
我完全不明白类型类的任何功能应该做什么,或者实现是如何工作的。
但我需要为 STT 实现它(http://hackage.haskell.org/package/STMonadTrans-0.3.1 给出的那个)
STT 有构造函数STT s m a
在我天真的尝试中,我尝试将所有 ST s 替换为 STT s m:
instance Monad m => PrimMonad (STT s m) where
type PrimState (STT s m) = s
primitive = STT
internal (STT p m) = p
但我收到此错误:
Not in scope: data constructor `STT'
对于primitive 和internal 的定义,尽管已经在整个程序中多次使用STT(尽管我猜它是一个类型构造函数?)。
我应该如何正确实现这个类型类?
(我最终会将其用作STT s (Rand g) a)
编辑:我导入Control.Monad.ST.Trans.Internal 以获取STT 作为数据构造函数,这些是新错误:(将internal (STT s m) 更改为internal (STT s) 后)
Couldn't match kind `*' against `ArgKind'
Kind incompatibility when matching types:
m0 :: * -> *
(#,#) (ghc-prim:GHC.Prim.State# (PrimState (STT s m))) :: ArgKind
-> (#)
In the expression: STT
In an equation for `primitive': primitive = STT
Couldn't match type `m'
with `(#,#) (ghc-prim:GHC.Prim.State# (PrimState (STT s m)))'
`m' is a rigid type variable bound by
the instance declaration at src/pimc/PIMC.hs:41:16
Expected type: ghc-prim:GHC.Prim.State# (PrimState (STT s m))
-> (# ghc-prim:GHC.Prim.State# (PrimState (STT s m)), a #)
Actual type: ghc-prim:GHC.Prim.State# s -> m (STTRet s a)
In the expression: p
In an equation for `internal': internal (STT p) = p
Couldn't match type `a' with `STTRet s a'
`a' is a rigid type variable bound by
the type signature for
internal :: STT s m a
-> ghc-prim:GHC.Prim.State# (PrimState (STT s m))
-> (# ghc-prim:GHC.Prim.State# (PrimState (STT s m)), a #)
at src/pimc/PIMC.hs:44:3
Expected type: ghc-prim:GHC.Prim.State# (PrimState (STT s m))
-> (# ghc-prim:GHC.Prim.State# (PrimState (STT s m)), a #)
Actual type: ghc-prim:GHC.Prim.State# s -> m (STTRet s a)
In the expression: p
In an equation for `internal': internal (STT p) = p
【问题讨论】:
-
您需要导入 the internal module 才能访问值构造函数。但是包裹的东西,
(State# s -> m (STTRet s a))的类型错误。对于primitive/internal,您需要返回状态和结果的元组。对于某些单子m,您可以编写一个实例,但据我所知,您不能编写一个通用实例。 -
@DanielFischer 已导入;但我遇到了你提到的错误。有关如何使其适用于特定 monad 的任何提示?
-
我认为没有办法解决您的问题。定义
primitive函数没有问题,但internal函数即使对于简单的monad(例如writer monad 或reader monad)也是有问题的。无论如何,我一直无法提出解决方案。我认为您必须以某种方式概括 PrimMonad 才能实现您想做的事情。 -
@svenningsson 我该怎么做?
-
我也在考虑编写自己的自定义组合 monad,但处理严格状态对我来说有点棘手