【发布时间】:2015-12-11 12:12:39
【问题描述】:
所以我有这个代码
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import MonadA
data A = A
newtype MonadA a => MyStateT a b { runMyStateT :: StateT A a b }
deriving (Functor, Applicative, Monad, MonadIO, MonadState A)
instance MonadTrans MyStateT where
lift = MyStateT . lift
我得到编译器抱怨它无法证明lift 的签名中的m 是MonadA 类型,或者这就是我阅读这些神秘错误消息的方式。
Could not deduce (MonadA m) arising from a use of `MyStateT'
from the context (Monad m)
bound by the type signature for
lift :: Monad m => m a -> MyStateT m a
有没有办法解决这个问题?我认为我需要约束才能实例化如下:
instance MonadA a => MonadA (MyStateT a) where
f = MyStateT . lift . f
f 的这种实现也可以吗? (由于上述错误,我没有走那么远)。我希望右侧的f 能够通过内部单子a 解析为f。
编辑:确实有助于删除newtype MonadA a => MyStateT ... 中的类型约束以避免我提到的确切错误。但是,我之前将另一个错误归咎于同一件事,请考虑上面示例代码的延续(某些部分重复,现在没有类型限制):
class MonadB m where
fB :: m ()
newtype MyStateT m a = MyStateT { runMyStateT :: StateT A m a}
deriving (... MonadState A ...)
instance MonadTrans MyStateT where
lift = MyStateT . lift
instance MonadA a => MonadA (MyStateT a) where
f = lift . f
instance MonadA a => MonadB (MyStateT a) where
fB = lift (modify (...))
错误是
Could not deduce (a ~ StateT A m0) from context (MonadA (MyStateT a), MonadA a)
在执行fB。早些时候我试过class MonadA m => MonadB m 无济于事。将a 与StateT A m 匹配甚至没有意义。由于MyStateT 是MonadState A 的一个实例,它应该可以工作,不是吗?
编辑:
好的,搞定了:
fB = MyStateT (modify ...)
我太傻了。
【问题讨论】:
标签: haskell typeclass monad-transformers type-constraints lifting