GHC 7.10.x迁移:为什么不能在实例中写一个"pure = return"Applicative?

O.P*_*ips 9 haskell ghc

我正在阅读一篇关于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

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... -}
Run Code Online (Sandbox Code Playgroud)

有NBs:DO NOT USE `pure = return`DO NOT USE `(*>) = (>>).为什么不能使用它?

PS我试图使用它,它已被编译.

zak*_*aps 7

正如@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(这可能更改的默认实现>>>> = *>),所以*> = >>不提倡向前兼容.