鉴于任意monad,有没有办法根据该monad创建monad变换器?我搜索了这个问题并没有看到它被解决的任何地方(虽然我可能已经错过了)所以我只是尝试自己做,而且我接近了,我想:
import Control.Monad.Trans.Class (MonadTrans, lift)
newtype ToMonadTrans m2 m1 a = ToMonadTrans (m2 (m1 a))
instance (Functor m2, Functor m1) => Functor (ToMonadTrans m2 m1) where
fmap f (ToMonadTrans x) = ToMonadTrans (fmap (fmap f) x)
instance (Applicative m2, Applicative m1) => Applicative (ToMonadTrans m2 m1) where
pure = ToMonadTrans . pure . pure
ToMonadTrans f <*> ToMonadTrans x = ToMonadTrans (((<*>) . (fmap (<*>))) f x)
instance (Monad m2, Monad m1) => Monad (ToMonadTrans m2 m1) where
ToMonadTrans x >>= ToMonadTrans f = ToMonadTrans (???)
instance Monad m2 => MonadTrans (ToMonadTrans m2) where
lift x = ToMonadTrans (pure x)
这里的想法是ToMonadTrans Maybe
与MaybeT
相同。这种方法的优点(如果它有效)是你可以将任何monad变成MonadTrans
,允许一个层叠任何monad而不必编写相应的专用变换器。
正如您所看到的,我实施了MonadTrans
以及Functor
和Applicative
,我遇到的唯一地方是Monad
。
我的问题是: