我正在阅读一篇关于GHC 7.10.x Migration的文章。有一些修复错误的建议。
GHC说
No instance for (Applicative ...)
如果GHC抱怨
Foo.hs:7:10: 没有实例声明的超类引起的(Applicative Foo)实例 在'Monad Foo'的实例声明中,修复此错误的一种简单方法是定义Applicative(可能还有Functor) 实例:实例Functor Foo在哪里 fmap = liftM - 或者: - fmap = m>> = pure。 ˚F
instance Applicative Foo where -- NB: DO NOT USE `pure = return` pure = {- move the definition of `return` from the `Monad` instance here -} (<*>) = ap {- defined in Control.Monad -} -- or alternatively: -- f1 <*> f2 = f1 >>= \v1 -> f2 >>= (pure . v1) -- NB: DO NOT USE `(*>) = (>>)` (*>) = {- move the definition of `>>` from the `Monad` instance here -} instance Monad Foo where return = pure {- definition moved to `Applicative(pure)` -} (>>) = (*>) {- definition moved to `Applicative((*>))` -} {- ...retain other previous definitions... -}
有NB:DO NOT USE `pure = return`
和DO NOT USE `(*>) = (>>)
。为什么不能使用它?
P.S。我试图使用它,它已被编译。
答案 0 :(得分:7)
正如@WillSewell在评论中暗示的那样,base-4.8.0.0
现在return
类型类Monad
中有一个默认实现:
class Applicative m => Monad m where
return :: a -> m a
return = pure
通过定义pure = return
并忘记手动实现return
,可能会创建一个无限循环的定义,它将通过编译并且只能在运行时检测到。
>>
目前是另一回事。它仅在>>=
上有一个默认的实现中继:
(>>) :: forall a b. m a -> m b -> m b
m >> k = m >>= \_ -> k
除非您在*> = >>
的定义中使用*>
,否则您将无法通过>>=
创建无限循环,但base
关于可能的下一个>>
中的重大更改(可能会将>> = *>
的默认实施更改为*> = >>
),因此不鼓励使用$redis-cli -h 127.0.0.1 -p 6379 -a mysupersecretpassword
进行向前兼容。