几个月后我才遇到这个问题,因为我想知道类似的事情。所以我想出了以下内容:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
import Control.Monad.Trans.Class
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.List
-- | Minimal implementation: either joinLift or joinT
class (MonadTrans t, Monad m) => MonadTransJoin t m | m -> t, t -> m where
joinLift :: (Monad m', Monad (t m')) => m' (m a) -> t m' a
joinLift = joinT . lift
joinT :: (Monad m', Monad (t m')) => t m' (m a) -> t m' a
joinT = (>>= (joinLift . return))
instance MonadTransJoin MaybeT Maybe where
joinLift = MaybeT
joinT = (>>= maybe mzero return)
instance MonadTransJoin ListT [] where
joinLift = ListT
joinT = (>>= foldr mcons mzero)
where mcons x xs = return x `mplus` xs
到目前为止一切都很好——我joinT
对ListT
/[]
对的方法看起来与 ehird 的choose
.
但问题在于,monad 转换器和其行为赋予其基本 monad 的 monad 之间实际上没有统一的接口。我们有MaybeT :: m (Maybe a) -> MaybeT m a
and ListT :: m [a] -> ListT m a
,但是我们有 OTOH StateT :: (s -> m (a, s)) -> StateT s m a
。我不知道是否有办法解决这个问题——这当然需要