2016-03-02 58 views
9

我在讀一篇關於GHC 7.10.x Migration的文章。有一些修復錯誤的建議。GHC 7.10.x遷移:爲什麼不能在實例Applicative中寫入「pure = return」?

GHC說No instance for (Applicative ...)

如果GHC抱怨

Foo.hs:7:10: 從實例聲明 的超出現在實例聲明沒有實例(應用型富)對於'Monad Foo'來說,修復這個錯誤的一個簡單方法是定義一個Applicative(也可能是一個Functor)實例:實例Functor Foo其中 fmap = liftM - 或者: - f map = m >> =純。 ˚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... -} 

有國家統計局:DO NOT USE `pure = return`DO NOT USE `(*>) = (>>)。爲什麼不能使用它?

P.S.我試圖使用它,它已被編譯。

+4

這將導致遞歸定義:'Monad'實例函數是根據'Applicative'實例函數定義的,因此您不能以其他方式進行。 –

回答

7

由於@WillSewell暗示的評論,從現在base-4.8.0.0return類型的類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 

*> = >>除非你在>>=的定義中使用*>你會不會創建一個無限循環,但也有some concern關於base今後可能發生重大變化(可能會將>>的默認實現更改爲>> = *>),因此不鼓勵使用*> = >>以實現向前兼容。

相關問題