![](/img/trans.png)
[英]Use cases for functor/applicative/monad instances for functions
[英]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.