是否可以创建以下签名的功能?
ExceptT A (ExceptT B m) () -> ExceptT B m A
我的想法是这样的,因为x
是上面提到的函数的参数(我和monad一起吮吸,所以它很可能是错误的。)
runExceptT x :: ExceptT B m (Either A ())
但是后来我陷入了Either A () -> A
之类的问题,因为它本身就要考虑Right
,因此要么失败要么返回A
的常量(我没有)。
但是,我知道x
的原始值恰好是左值之一,否则定义会无限循环。
答案 0 :(得分:2)
我有一些类型为
x
的[ExceptT B m ()
]值。该值可以是左侧或右侧。但是,我会forever x
,然后它会在某个时刻离开(m
为StateT
),或者它永远不会终止。
问题是您过早地将结果类型修改为()
。当您运行操作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
,这意味着您可以拥有B
,Either B A
或什么都没有。
Left b
类型的值可以是Right a
或awesomeFunction
。让我们尝试实施awesomeFunction (Left b) = Left b
awesomeFunction (Right (Left a)) = Right a
awesomeFunction (Right (Right ()) = ???
。
Right (Right ()
在这种情况下,我们什么都没有(A
),我们无法从空中创建{{1}},因此无法创建此功能。