私はこれに似たものがあると思っていたので、数ヶ月後にこの質問に出会いました。だから私は、次のを思い付いた:
{-# 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
とは何かを持っているように見えます。
しかし、この問題は、実際にはモナド変圧器とそれが基本モナドに与えるモナドとの間に一様なインターフェースがないことです。 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