所以真实世界Haskell 说:
每个monad变换器都是MonadTrans的实例
但我正在玩 Scotty 并发现它的基础monad转换器ScottyT
不是 MonadTrans
的实例。
查看发行说明,这似乎是一个深思熟虑的设计决策:here。引用:
ScottyT的monad参数已经解耦,导致ScottyT构造函数的类型发生变化。因此,ScottyT不再是MonadTrans实例......
我希望你理解我的困惑。不过,我会尝试制定严格的问题:
MonadTrans
的实例? P.S。:我明白我可以自己定义一个MonadTrans ScottyT
的实例,但是我应该这样做吗? (回到问题链接)
答案 0 :(得分:10)
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
没有&#39}实际上是实现了这样的组合。