提取嵌套的ExceptT monad变换器的左值

时间:2015-09-07 16:12:12

标签: haskell monads monad-transformers

是否可以创建以下签名的功能?

ExceptT A (ExceptT B m) () -> ExceptT B m A

我的想法是这样的,因为x是上面提到的函数的参数(我和monad一起吮吸,所以它很可能是错误的。)

runExceptT x :: ExceptT B m (Either A ())

但是后来我陷入了Either A () -> A之类的问题,因为它本身就要考虑Right,因此要么失败要么返回A的常量(我没有)。

但是,我知道x的原始值恰好是左值之一,否则定义会无限循环。

2 个答案:

答案 0 :(得分:2)

OP在评论中澄清:

  

我有一些类型为x的[ExceptT B m ()]值。该值可以是左侧或右侧。但是,我会forever x,然后它会在某个时刻离开(mStateT),或者它永远不会终止。

问题是您过早地将结果类型修改为()。当您运行操作forever时,您将获得所需的任何结果类型。特别是,您可以将左侧和右侧固定为相同的类型,突然一切都正常。也就是说,您可以编写类似

的内容
either return return =<< runExceptT (forever x)

并且您最终会得到一个动作,如果发生异常,则返回异常。

答案 1 :(得分:1)

简短回答:那是不可能的。

答案很长:ExceptT e m a包含m (Either e a),因此ExceptT A (ExceptT B m) ()包含ExceptT B m (Either A ()),而m (Either B (Either A ()))又包含m (Either B A)。问题是:我们如何从那里获得m

让我们忘掉awesomeFunction :: Either B (Either A ()) -> Either B A ,因为它并不重要。我们想要一个功能:

Either B (Either A ())

Left b类型的值可以是Right (Left a)Right (Right ())A,这意味着您可以拥有BEither B A或什么都没有。

Left b类型的值可以是Right aawesomeFunction。让我们尝试实施awesomeFunction (Left b) = Left b awesomeFunction (Right (Left a)) = Right a awesomeFunction (Right (Right ()) = ???

Right (Right ()

在这种情况下,我们什么都没有(A),我们无法从空中创建{{1}},因此无法创建此功能。