将每个monad变换器作为MonadTrans的实例是否真的是一种默认做法?

for*_*ker 9 monads haskell monad-transformers scotty

所以真实世界Haskell说:

每个monad变换器都是MonadTrans的一个实例

但我玩斯科蒂,并发现它的基础单子转换ScottyT没有的一个实例MonadTrans.

看一下发行说明,这似乎是一个刻意的设计决定:这里.引用:

ScottyT的monad参数已经解耦,导致ScottyT构造函数的类型发生变化.因此,ScottyT不再是MonadTrans实例......

我希望你理解我的困惑.不过,我会尝试制定严格的问题:

  • 为什么不想让monad变换器成为一个实例MonadTrans呢?
  • 您如何解释上述ScottyT设计的变化?

PS:我明白我可以定义一个MonadTrans ScottyT自己的实例,但是我应该吗?(回到问题链接)

lef*_*out 10

ScottyT不是monad变压器.让我们内联(简化)定义:

newtype ScottyT' m a = ScottyT' {
   runS :: State [ (Request->m Response) -> Request->m Response ] a
  }
Run Code Online (Sandbox Code Playgroud)

要为此定义lift,您需要从一般m a操作和此类中间件列表中获取实际a值,因为State s产生实际的非单值.没有办法做到这一点.

现在,如果你认为MonadTrans实际上并不需要某个monad变换器:从数学上讲,monad变换器对应于仿函数的组合,但ScottyT实际上并没有实现这样的组合.