9

所以真实世界的 Haskell说:

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

但我正在和Scotty一起玩,发现它的基本单子转换ScottyT不是MonadTrans.

查看发行说明,似乎这是一个经过深思熟虑的设计决定:here。引用:

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

我希望你能理解我的困惑。尽管如此,我将尝试提出严格的问题:

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

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

4

1 回答 1

10

ScottyT不是单子变压器。让我们内联(简化的)定义:

newtype ScottyT' m a = ScottyT' {
   runS :: State [ (Request->m Response) -> Request->m Response ] a
  }

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

现在,如果您认为MonadTrans某些东西实际上不需要成为 monad 转换器:从数学上讲,monad 转换器对应于函子的组合,但ScottyT实际上并没有实现这样的组合。

于 2015-09-29T23:09:28.157 回答