GHC可以为monad变压器派生Functor和Applicative实例吗?

我试图以mtl库的精神实现MaybeT 。 有了这个非编译解决方案:

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}

import Control.Monad
import Control.Monad.Trans
import Control.Monad.State

newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }

instance (Monad m) => Monad (MaybeT m) where
    x >>= f = MaybeT $ runMaybeT x >>= maybe (return Nothing) (runMaybeT . f)
    return a = MaybeT $ return (Just a)
    fail _ = MaybeT $ return Nothing

instance MonadTrans MaybeT where
     lift m = MaybeT (liftM Just m)

instance (MonadIO m) => MonadIO (MaybeT m) where
    liftIO m = lift (liftIO m)

instance (MonadState s m) => MonadState s (MaybeT m) where
    get = lift get
    put = lift . put

...

我收到错误:

由于上下文中的实例声明的超类(Monad m)导致无法推论(Applicative(MaybeT m)),

如果我执行以下内容,它会编译:

instance (Monad m) => Applicative (MaybeT m) where
    pure = return
    (<*>) = ap 

instance (Monad m) => Functor (MaybeT m) where
    fmap = liftM

GHC能为我做这个吗?


不,GHC目前不能这样做。 也许在未来它会。

增加应用实例的需求是一个相当新的实例,引入了GHC 7.10和“烧尽所有桥梁”提案。 这固定了以前类层次结构的一些瑕疵,最终要求monad是函子的子类的应用程序的子类。 不幸的是,这破坏了向后兼容性,并且由于没有自动的方式来推断应用实例而导致一些不便。

也许在未来GHC将允许类似的东西

class Applicative m => Monad m where
   return :: a -> m a
   (>>=) :: m a -> (a -> m b) -> m b
   default pure = return
   default (<*>) = ap

这样就不需要明确超类实例。 甚至是基于Haskell模板的东西,这样图书馆作者就可以向GHC解释如何自动导出实例(这在某种程度上现在是可行的)。 我们将看到什么来自GHC开发者。


GHC很可能能够派生出Functor实例,因为它很好。 但是它知道派生一个Applicative实例的唯一方法是使用广义的新类型派生,这在这里不适用。

链接地址: http://www.djcxy.com/p/33217.html

上一篇: Can GHC derive Functor and Applicative instances for a monad transformer?

下一篇: Functor / Applicative instances for State in Haskell