簡體   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