【发布时间】:2016-06-18 07:07:48
【问题描述】:
我有一个 monad 转换器堆栈的类型别名:
type KStat s a = ReaderT (KStatRoot s) (ExceptT KindError (ST s)) a
我需要将用户从这种类型中抽象出来,主要是因为KStatRoot 结构导致了循环依赖。因此,我创建了一个单独的模块并为它定义了一个类型类:
class (Monad (m s), MonadError KindError (m s)) =>
MStat m s where
liftToST :: ST s a -> m s a
kstatNewRef :: a -> m s (STRef s a)
kstatReadRef :: STRef s a -> m s a
kstatWriteRef :: STRef s a -> a -> m s ()
这个定义可以编译(虽然需要{-# LANGUAGE MultiParamTypeClasses,FlexibleContexts #-} 才能工作,但我明白为什么这两个都是必需的),我已经能够将一些使用站点转换为类型类并让它们进行类型检查,所以一切那里似乎还可以。但是我正在努力弄清楚如何为该类定义我的实例:
instance MStat (KStat s a) s where
liftToST = lift . lift
kstatNewRef = liftToST . newSTRef
kstatReadRef = liftToST . readSTRef
kstatWriteRef r v = liftToST $ writeSTRef r v
给我错误:
src/KindLang/Data/KStat.hs:27:17:
The first argument of ‘MStat’ should have kind ‘* -> * -> *’,
but ‘KStat s a’ has kind ‘*’
In the instance declaration for ‘MStat (KStat s a) s’
哪种有意义,但是如果我在实例标头中将KStat s a 更改为KStat,我会收到此错误:
src/KindLang/Data/KStat.hs:27:10:
Type synonym ‘KStat’ should have 2 arguments, but has been given none
In the instance declaration for ‘MStat KStat s’
这似乎基本上是在说完全相反的。
我在声明实例的模块中使用这些语言扩展:
{-# LANGUAGE RankNTypes, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-}
如何解决这些错误?
显示错误的完整文件如下:
{-# LANGUAGE RankNTypes, TypeSynonymInstances, FlexibleContexts,
FlexibleInstances, MultiParamTypeClasses #-}
import Control.Monad.Except
import Control.Monad.ST
import Control.Monad.Reader
import Data.STRef
data KStatRoot s = KStatRoot
data KindError
class (Monad (m s), MonadError KindError (m s)) =>
MStat m s where
liftToST :: ST s a -> m s a
kstatNewRef :: a -> m s (STRef s a)
kstatReadRef :: STRef s a -> m s a
kstatWriteRef :: STRef s a -> a -> m s ()
type KStat s a = ReaderT (KStatRoot s) (ExceptT KindError (ST s)) a
instance MStat (KStat s m) s where
liftToST = lift . lift
kstatNewRef = liftToST . newSTRef
kstatReadRef = liftToST . readSTRef
kstatWriteRef r v = liftToST $ writeSTRef r v
【问题讨论】:
-
你能提供一个完整的导入示例吗?
-
@ErikR - 所涉及的完整文件相当大,但如果你能给我一些线索你想要达到的目标,也许我可以解决一些问题?
-
只举一个简单的例子来说明问题。
-
@ErikR - 好的,添加了一个模块,所有内容都在同一个地方,给出了相同的错误。