我正在阅读一篇关于GHC 7.10.x Migration的文章.有一些修复错误的建议.
GHC说
No instance for (Applicative ...)如果GHC抱怨这一点
Foo.hs:7:10:没有实例声明的超类引起的(Applicative Foo)实例在'Monad Foo'的实例声明中,修复此错误的一种简单方法是定义一个Applicative(可能还有一个Functor) )instance:instance Functor Foo,其中fmap = liftM - 或者: - fmap = m >> = pure.F
Run Code Online (Sandbox Code Playgroud)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... -}
有NBs:DO NOT USE `pure = return`和DO NOT USE `(*>) = (>>).为什么不能使用它?
PS我试图使用它,它已被编译.
正如@WillSewell在评论中暗示的那样,从base-4.8.0.0现在开始return,类型类中Monad有一个默认实现:
class Applicative m => Monad m where
return :: a -> m a
return = pure
Run Code Online (Sandbox Code Playgroud)
通过定义pure = return并忘记return手动实现,可以创建一个无限循环的定义,它将传递编译并且只能在运行时检测到.
>>现在是一个不同的故事.它只有一个默认的实现中继>>=:
(>>) :: forall a b. m a -> m b -> m b
m >> k = m >>= \_ -> k
Run Code Online (Sandbox Code Playgroud)
和*> = >>你,除非你使用不会产生无限循环*>中的定义>>=,但也有一些担忧有关在今后可能发生重大变化base(这可能更改的默认实现>>到>> = *>),所以*> = >>不提倡向前兼容.