Monad 作为申请人的子类

从 GHC 7.10 开始,ApplicativeMonad 的超类(即,每种类型的 Monad 也必须是 Applicative)。Applicativepure<*>)的所有方法都可以用 Monadreturn>>=)的方法来实现。

很明显,purereturn 服务于同等目的,所以 pure = return<*> 的定义过于清晰:

mf <*> mx = do { f <- mf; x <- mx; return (f x) }                 
       -- = mf >>= (\f -> mx >>= (\x -> return (f x)))
       -- = [r   | f <- mf, x <- mx, r <- return (f x)]   -- with MonadComprehensions
       -- = [f x | f <- mf, x <- mx]                   

此功能在标准库中定义为 ap

因此,如果你已经为类型定义了 Monad 的实例,那么你可以通过定义免费获得 Applicative 的实例

instance Applicative < type > where
    pure  = return
    (<*>) = ap

与 monad 准则一样,这些等效性并未得到执行,但开发人员应确保始终坚持这些等效性。