为monad变压器派生Functor和Applicative实例

为monad变压器派生Functor和Applicative实例

本文介绍了GHC可以为monad变压器派生Functor和Applicative实例吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

import Control.Monad
import Control.Monad.Trans $ b $ import Control.Monad.State
$ b $ newtype MaybeT ma = MaybeT {runMaybeT :: m(也许a)}

instance(Monad m)=> Monad(MaybeT m)其中
x>> = f = MaybeT $ runMaybeT x>> = maybe(return Nothing)(runMaybeT。f)
return a = MaybeT $ return(Just a)
失败_ = MaybeT $返回Nothing

实例MonadTrans MaybeT其中
lift m = MaybeT(liftM只是m)

实例(MonadIO m)= > MonadIO(MaybeT m)其中
liftIO m =电梯(liftIO m)

实例(MonadState s m)=> MonadState s(MaybeT m)其中
get = lift得到
put = lift。把

...

我得到错误:

如果我执行以下步骤,它会编译:

  instance(Monad m)=>应用(MaybeT m)其中
pure =返回
(*)= ap

实例(Monad m)=> Functor(MaybeT m)其中
fmap = liftM

GHC可以帮我吗? / p>

解决方案

不,GHC目前无法做到这一点。也许在未来它会。



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

可能在未来GHC将允许像

  class Applicative m => Monad m其中
return :: a - > m a
(>> =):: m a - > (a - > m b) - > mb
default pure = return
default(*)= ap




I'm trying to implement MaybeT in the spirit of the mtl library. With this non-compiling solution:

{-# 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

...

I get the error:

If I implement the following, it compiles:

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

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

Can GHC do this for me?

解决方案

No, GHC can not currently do that. Maybe in the future it will.

The need to add applicative instances is a fairly new one, introduced with GHC 7.10 and the "burn all bridges" proposal. This fixed some warts of the previous class hierarchy, by finally requiring that monads are subclasses of applicatives which are subclasses of functors. Unfortunately, this breaks backward compatibility, and causes some inconveniences since there's no automatic way to infer the applicative instances.

Perhaps in the future GHC will allow something like

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

so that one does not need to be explicit about the superclass instances. Or even something based on Template Haskell, so that a library writer can explain to GHC how to automatically derive instances (which, to some extent, is feasible right now). We shall see what comes from the GHC developers.

这篇关于GHC可以为monad变压器派生Functor和Applicative实例吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 15:43