Haskell中为何使用pure需依赖Monad?GameStep实例报错解析
问题解答
首先得明确:你要实现GameStep的Applicative实例,但它的底层是ReaderT BoardInfo (StateT GameState m) a,问题出在StateT的Applicative实例本身就需要Monad m约束。
先看StateT的标准库实现:
instance Monad m => Applicative (StateT s m) where pure a = StateT $ \s -> pure (a, s) StateT mf <*> StateT mx = StateT $ \s -> do (f, s') <- mf s (x, s'') <- mx s' pure (f x, s'')
这里的pure确实只用到了Applicative m,但<*>的实现用了do语法(本质是>>=),这就要求m是Monad。因为Applicative实例必须同时提供pure和<*>,所以整个StateT s m的Applicative实例必须加上Monad m的约束。
回到你的GameStep,它是ReaderT套StateT,而ReaderT的Applicative实例只需要内层的m是Applicative。但内层的StateT GameState m要成为Applicative,就必须满足Monad m。所以你的GameStep的Applicative实例必须加上Monad m约束,哪怕pure本身不需要——因为<*>的实现绕不开这个约束。
简单说:不是pure需要Monad m,而是你要实现完整的Applicative实例,其中<*>的实现依赖这个约束。
内容的提问来源于stack exchange,提问作者panic
相关产品推荐
相关产品推荐

