为什么没有必要使用电梯在内部monad变压器环境中执行功能,IO除外?我的意思是,如果我在WritT上有StateT而在WritT上有WriterT,为什么我能这样做呢?
tell $ {- any code here for the Writer -}
foo <- asks {- This for the reader -}
and so on...
而不是
lift $ tell $ {- code ... -}
...
是否有特殊的解释或只是Monad变形金刚的写作方式?
答案 0 :(得分:7)
这是因为Monad Transformer Library(MTL)认识到以这种方式堆叠monad是很常见的,因此他们不会将tell
定义为某个函数(Mondoid w) => w -> Writer ()
。
相反,他们有MonadWriter
,它被定义为一个类型类,其中包含tell作为函数。然后,他们定义了大量MonadWriter
:ReaderT
,IO
,Writer
(duh)等实例。因此,您可以避免恼人的重复lift.
。
这很常见,任何monad变换器(在MTL中)都会有一个Control.Monad.***.Class
,它具有这种类型类。