繁体   English   中英

GHC可以为单子变换器导出Functor和Applicative实例吗?

[英]Can GHC derive Functor and Applicative instances for a monad transformer?

我正在尝试以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

...

我收到错误:

无法推断(Applicative(MaybeT m))来自上下文中的实例声明的超类(Monad 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

因此,不需要明确超类实例。 甚至基于Template Haskell的东西,以便库编写者可以向GHC解释如何自动派生实例(在某种程度上,这在当前是可行的)。 我们将看到来自GHC开发人员的内容。

GHC很可能能够派生出Functor实例,因为它在那些方面相当不错。 但它知道派生Applicative实例的唯一方法是使用广义newtype派生,这里不适用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM