Haskell中向其他线程抛出异常的操作语义

Haskell中向其他线程抛出异常的操作语义,haskell,semantics,Haskell,Semantics,我读过SPJ的论文,大部分内容都很容易理解,但我并不完全理解分离线以上这两个条件的确切含义: 论文中指出,它们在这里是为了确保第二个上下文(E2)是最大的,即它包括所有活动捕获。然而,我并不完全明白这意味着什么。这是否意味着如果在第二个线程中有一个catch,则不会抛出异常?但是为什么bind也在那里呢 直观地说,它用于以确定的方式在正确的位置“插入”异常ioError e 考虑M=catch(threadDelay 1000000)someHandler。我们有: M = Ea[M]

我读过SPJ的论文,大部分内容都很容易理解,但我并不完全理解分离线以上这两个条件的确切含义:


论文中指出,它们在这里是为了确保第二个上下文(E2)是最大的,即它包括所有活动捕获。然而,我并不完全明白这意味着什么。这是否意味着如果在第二个线程中有一个
catch
,则不会抛出异常?但是为什么bind也在那里呢

直观地说,它用于以确定的方式在正确的位置“插入”异常
ioError e

考虑
M=catch(threadDelay 1000000)someHandler
。我们有:

M = Ea[M]
   where Ea[x] = x
M = Eb[M']
   where Eb[x] = catch x someHandler
         M' = threadDelay 1000000
如果没有附带条件,我们将有两个不同的操作步骤,使得语义不确定性:

{throwTo t e}s | {M}t ==> {return ()}s | {Ea[ioError e]}t
                        = {return ()}s | {ioError e}t
{throwTo t e}s | {M}t ==> {return ()}s | {Eb[ioError e]}t
                        = {return ()}s | {catch (ioError e) someHandler}t
在前一种情况下,错误不会被捕获,而在后一种情况下则会被捕获。侧条件确保只有后者是有效步骤

Bind也可以避免替换以下内容中的所有内容:

M = catch (threadDelay 1000000) someHandler >>= something
在这里,如果您只需要“
M
而不是catch”,您可以再次选择
M=Ea[M]
并替换所有代码。相反,次要条件迫使您进行选择

Ec[x] = catch x someHandler >>= something

然后将
ioError e
插入
catch

中的正确位置,啊,我明白了,谢谢!我必须重新阅读评估上下文的定义才能最终理解它:评估上下文必须用一个术语来填补漏洞,值是一个术语,
M>>=N
是一个值,因此我们需要确保不替换它。