我正在用https://github.com/lsmor/snake-fury/学习Haskell。exercise 4中的一个任务是“为新类型实现Applicative
示例”,其中新类型是
newtype GameStep m a = GameStep {runGameStep :: ReaderT BoardInfo (StateT GameState m) a}
字符串
这是我的第一次尝试,没有编译。
instance (Applicative m) => Applicative (GameStep m) where
pure a = GameStep $ pure a
(GameStep r) <*> (GameStep s) = GameStep $ r <*> s
型
GHC说,
• Could not deduce (Monad m) arising from a use of ‘pure’
from the context: Applicative m
bound by the instance declaration at src/GameState.hs:55:10-52
Possible fix:
add (Monad m) to the context of
the type signature for:
pure :: forall a. a -> GameStep m a
or the instance declaration
型
(and <*>
使用相同)
如果我按照建议将(Applicative m) => ...
替换为(Monad m) => ...
,它会编译。但我不理解这个错误消息,因为pure
(以及<*>
)是为Applicative
定义的,而不是为Monad
定义的。
如有任何建议,我们将不胜感激。
1条答案
按热度按时间kh212irz1#
这是因为您的
m
被 Package 在StateT
内部(然后 Package 在ReaderT
中,但这并没有增加任何内容)。当您写入
GameStep $ pure a
时,pure a
必须不仅返回m a
,还返回ReaderT _ (StateT _ m) a
如果你查看
StateT
的文档,你会看到Applicative
被定义为:字符串
所以不是你自己的示例需要
Monad
,而是StateT
的示例。现在,
StateT
需要Monad
的原因是,为了实现<*>
,它需要执行两个参数,但对于StateT
,执行顺序很重要,因此<*>
的StateT
实现必须使用底层Monad
的>>=
定义参数执行的顺序,并在它们之间线程化状态。