让每个 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 ...
希望你能理解我的困惑。不过,我会尝试制定严格的问题:
- 为什么不希望 monad 转换器成为
MonadTrans
的实例?
- 您如何解释 ScottyT 设计中的上述变化?
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
不是实际实现这样的组合
所以 现实世界 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 ...
希望你能理解我的困惑。不过,我会尝试制定严格的问题:
- 为什么不希望 monad 转换器成为
MonadTrans
的实例? - 您如何解释 ScottyT 设计中的上述变化?
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
不是实际实现这样的组合