不管是好是坏,Haskell 流行的Servant库使得在涉及ExceptT err IO
. Servant 自己的处理程序 monad 是ExceptT ServantErr IO
. 正如许多人所说,这是一个有点麻烦的 monad,因为有多种方式无法展开:1)通过IO
基础的正常异常,或 2)通过返回Left
。
正如 Ed Kmett 的exceptions
图书馆所帮助澄清的那样:
基于延续的 monad 和
ErrorT e IO
提供多种故障模式的堆栈是此类 [MonadMask
] 的无效实例。
这非常不方便,因为MonadMask
让我们可以访问有用的 [多态版本]bracket
函数来进行资源管理(不会由于异常等而泄漏资源)。但是在Servant的Handler
monad中我们不能使用它。
我对它不是很熟悉,但有些人说解决方案是使用monad-control
它,它是许多合作伙伴库喜欢的lifted-base
,并且lifted-async
可以让你的 monad 访问资源管理工具,比如bracket
(大概这也适用于ExceptT err IO
和朋友?)。
但是,它似乎在社区monad-control
中失去了青睐,但我无法确定替代方案是什么。甚至 Snoyman 最近safe-exceptions
的库也使用了 Kmett 的exceptions
库并避免了monad-control
.
有人可以为像我这样试图认真使用 Haskell 的人澄清当前的故事吗?