我认为不可能编写带有签名的函数:
changeReaderT :: (MonadTrans m)
=> (r -> r')
-> m (ReaderT r IO) a
-> m (ReaderT r' IO) a
问题是,一般来说,对第二个论点唯一可能的操作是将其提升到
t (m (ReaderT r IO)) a
对于某些单声道变压器
t
,这不会给你买任何东西。
也就是说
MonadTrans m
仅约束本身并不能提供足够的结构来做您想要做的事情。你要么需要
m
作为typeclass的实例,如
MFunctor
mmorph
该软件包允许您通过提供以下功能以常规方式修改monad堆栈的内层:
hoist :: Monad m => (forall a. m a -> n a) -> t m b -> t n b
(胡安·巴勃罗·桑托斯就是这么说的),否则你需要一种能力来挖掘你的大脑结构
monad transformer将部分运行并重建它(这将是特定于transformer的)。
hoist
从
mmorph
m
已经由变压器组成,由
type M n = MaybeT (StateT String n)
action :: M (ReaderT Double IO) a
action = undefined
f :: Int -> Double
f = fromIntegral
desired :: M (ReaderT Int IO) a
desired = (hoist $ hoist $ withReaderT fromIntegral) action
你需要一个
升起
M
.
第二种方法避免了
和必要的
MFunctor公司
实例,但需要根据您的具体情况进行裁剪
M
. 对于上述类型,它看起来像:
desired' :: M (ReaderT Int IO) a
desired' = MaybeT $ StateT $ \s ->
(withReaderT fromIntegral . flip runStateT s . runMaybeT) action
你基本上需要把单子运行到
ReaderT
然后将其重建,将层视为
StateT
小心。这正是
中的实例
mmorph