我試圖以mtl
庫的精神實現MaybeT
。有了這個非編解決方案:GHC可以派生函數和應用實例的單子變壓器嗎?
{-# 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
...
我得到的錯誤:
Could not deduce (Applicative (MaybeT m)) arising from the superclasses of an instance declaration from the context (Monad m)
如果我執行以下,它編譯:
instance (Monad m) => Applicative (MaybeT m) where
pure = return
(<*>) = ap
instance (Monad m) => Functor (MaybeT m) where
fmap = liftM
GHC能爲我做到這一點?
相關:http://stackoverflow.com/questions/18861231/why-is-there-no-xderiveapplicative-extension – dfeuer