幾個月後,我剛剛遇到了這個問題,因爲我想知道類似這樣的事情。所以,我想出了以下內容:
{-# 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
到目前爲止好,我爲ListT
/[]
對joinT
方法看起來像它有事情做與ehird的choose
。
但是,這樣做的問題是monad變換器和monad的行爲之間並沒有統一的接口,monad的行爲賦予它的基本monad。我們有MaybeT :: m (Maybe a) -> MaybeT m a
和ListT :: m [a] -> ListT m a
,但是OTOH我們有StateT :: (s -> m (a, s)) -> StateT s m a
。我不知道是否有辦法解決這個問題 - 它肯定需要
是的,我同意'conv'是一個簡單的函數。我只是感到驚訝,它不在那裏。 「ListT」模塊中幾乎沒有任何實用程序,這讓我覺得我重新發明了方向盤。就這樣。 – julkiewicz 2012-02-09 16:41:37