Haskell中Monad Transformer自动省略lift的实现原理探究
Monad Transformer中省略lift的原理
你的猜测不对——这不是GHC的临时扩展,而是依赖mtl库(Haskell生态中最常用的monad transformer工具库)的类型类设计实现的,核心是利用Haskell的类型类多态特性。
核心逻辑:mtl的层级类型类实例
mtl为每个monad transformer定义了对应上层类型类的实例,当底层monad支持某个类型类(比如MonadWriter)时,上层的transformer会自动继承这个类型类的能力,自动帮你完成lift操作。
以你的例子来说:
- 你的
Foo类型是ReaderT String (WriterT String Identity) Int,其中内层的WriterT String Identity是MonadWriter String的实例(自带tell操作)。 - mtl为
ReaderT r m定义了**当m是MonadWriter w时,ReaderT r m也自动成为MonadWriter w**的实例,实例中tell的实现就是lift . tell:
instance (MonadWriter w m) => MonadWriter w (ReaderT r m) where tell = lift . tell -- 其他方法listen、pass的实现略
所以你在ReaderT的do块中直接调用tell时,GHC会自动匹配这个实例,替你完成lift的工作,不需要手动写lift $ tell ...。
扩展说明
这种设计同样适用于其他mtl类型类,比如MonadReader、MonadState:只要你的monad栈中某一层支持对应的类型类,上层的transformer实例会自动把操作“透传”到底层,省去手动嵌套lift的麻烦。
内容的提问来源于stack exchange,提问作者Xiangzhi Liu
相关产品推荐
相关产品推荐

