2

使用管道,我正在尝试为ProxyFastProxyCorrect类型编写MonadTransControl实例。这就是我所拥有的:

instance MonadTransControl (ProxyFast a' a b' b) where
  data StT (ProxyFast a' a b' b) a = StProxy { unStProxy :: ProxyFast a' a b' b Identity a}
  liftWith = undefined
  restoreT = undefined

我不知道如何编写liftWith 或restoreT。其他单子转换器的实例都使用“交换”单子的函数,例如 EitherT ema -> m (EitherT e Identity a),但我在管道中找不到任何这样的函数。ProxyCorrect / ProxyFast 的 MonadTransControl 实例如何?还是不能写一个?(如果是,是否可以在管道 4.0 中使用?)

4

1 回答 1

5

感谢您的链接,现在我可以给出更好的答案。

不,没有办法实现这一点,使用任一版本的pipes. 原因是MonadTransControl期望 monad 转换器构建在底层基础 monad 的单层之上。对于当前实现的所有 monad 转换器都是如此MonadTransControl,例如:

ErrorT  ~ m (Either e r)
StateT  ~ s -> m (r, s)
WriterT ~ m (r, w)
ReaderT ~ i -> m r
ListT   ~ m [r]  -- This version of ListT is wrong, and the true ListT
                 -- would not work for `MonadTransControl`

但是, aProxy不会包装基础单子的单层。这对于两个pipes版本都是如此,您可以根据需要嵌套尽可能多的基本 monad 层。

事实上,任何多次嵌套基本 monad 的 monad 转换器都会反抗一个MonadTransControl实例,例如:

FreeT     -- from the `free` package
ListT     -- when done "right"
ConduitM  -- from the `conduit` package

然而,仅仅因为pipes不实施MonadTransControl并不意味着所有的希望都失去了。 pipes-safe实现了人们通常期望的许多操作MonadTransControl,例如bracket获取资源,因此如果您可以详细说明您的特定用例,我可以告诉您更多信息,如果有适合pipes您的问题的基于 - 的解决方案。

于 2013-07-07T19:31:41.793 回答