Data.Vector.Mutable似乎需要PrimMonad在ST s和IO monads中的一个实例。
类型化定义为--
-- | 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
在我天真的尝试中,我尝试用STT s m替换所有的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发布于 2013-08-01 06:28:35
主要而言,您可能能够为原语编写实现,但不能为内部实现编写实现,因为它为您的monad强加了某种结构,这只能由IO和ST monad的内部实现来满足。
然而,我的印象是,问题在于Data.Vector.Mutable模块,它的要求过于严格。例如,要在单模m中使用IO向量,您主要只需要将IO嵌入到m(即原语方法)中,而不是相反(即内部方法)。如果这是正确的,则应该尝试将PrimMonad类细分为嵌入部分和同构部分,例如:
-- | Class of primitive state-transformer monads
class Monad m => PrimMonadEmbed m where
-- | State token type
type PrimState m
-- | Execute a primitive operation
primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
class PrimMonadEmbed m => PrimMonad m where
-- | Expose the internal structure of the monad
internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)这在向后兼容性方面可能是可以的,因为用户代码中不存在自定义实例。使需求不那么严格也会使它们的代码在IO monad的转换版本(如StateT、Int、IO等)中可用。
你可以尝试两件事:
顺便说一句,下面的原语实现应该可以工作(比较STT的来源以了解代码中的错误):
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
module Test where
import Control.Monad.Primitive
import Control.Monad.ST.Trans
import Control.Monad.ST.Trans.Internal
instance Monad m => PrimMonad (STT s m) where
type PrimState (STT s m) = s
primitive f = STT (\s -> case (f s) of (# s', v #) -> return (STTRet s' v))
internal _ = error "no implementation of internal for STT"https://stackoverflow.com/questions/17522198
复制相似问题