让每个 monad 转换器成为 MonadTrans 的实例真的是默认做法吗?

Is it really a default practice to make every monad transformer an instance of MonadTrans?

所以 现实世界 Haskell 说:

Every monad transformer is an instance of MonadTrans

但我正在玩 Scotty 并发现它的基础 monad 转换器 ScottyT 不是 的一个实例MonadTrans.

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

The monad parameters to ScottyT have been decoupled, causing the type of the ScottyT constructor to change. As a result, ScottyT is no longer a MonadTrans instance ...

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

P.S.: 我知道我可以自己定义一个 MonadTrans ScottyT 的实例,但是我应该吗? (链接回问题)

ScottyT 不是 monad 转换器。让我们内联(简化的)定义:

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

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

现在,如果您争辩说 MonadTrans 实际上并不是成为 monad 转换器所必需的:从数学上讲,monad 转换器对应于函子的组合,但 ScottyT 不是实际实现这样的组合