Fed*_*ico 3 haskell lazy-evaluation strictness
在https://en.wikibooks.org/wiki/Haskell/Denotational_semantics#Pattern_Matching页面上,进行以下练习:
考虑
or具有以下属性的两个布尔参数的函数:
- 要么 ??=?
- 还是真的?=真
- 要么 ?正确=正确
- 或假y = y
- 或x假= x
此功能是联合严格性的另一个示例,但更加严格:结果仅是?如果两个参数都是(至少在我们将参数限制为True和?时)。这样的功能可以在Haskell中实现吗?
该功能可用下表表示:
| ? | False | True
------|-----------------------
? | ? | ? | True
False | ? | False | True
True | True | True | True
Run Code Online (Sandbox Code Playgroud)
根据https://en.wikibooks.org/wiki/Haskell/Denotational_semantics#Monotonicity中给出的定义,此功能是单调的,因此我看不出有理由排除在Haskell中实现此功能的可能性。但是,我没有实现它的方法。
练习的答案是什么?
PS:我得到的答案是“不,你不能”。我正在寻找的是严格的证明。我觉得我对可以定义什么功能缺少一些重要的限制。绝对不是所有的单调函数。
假设您要进行评估or x y。为此,您必须选择一个或另一个自变量,以查看对其求值是否导致True或False。如果您猜对了,您将弄清楚结果是应该是True还是False不需要评估另一个参数(可能是?)。
但是,如果您猜错了,您将永远无法完成对参数的求值。否则您将陷入无限循环,或者会遇到运行时错误。
并发允许您并行评估两个参数[1]。假设两个参数之一求得适当值Boolean,则两个分支之一将成功找到它。另一个分支将引发错误(在这种情况下,您可以简单地丢弃该分支并忽略该错误),或者陷入循环中(当另一个分支成功时,可以强制终止该循环)。无论哪种方式,您最终都可以得到正确的答案。
当然,如果两个参数都导致?,则隐式结果or仍然是?;。您无法完全绕过暂停问题。
[1]“平行”并不是说要分叉另一个过程并同时对其进行评估。您可以为N步长求值一个参数(获取一些值N以及“步长”的含义);如果引发错误,请放弃并尝试另一个参数,如果尚未终止,请挂起该线程,然后尝试另一个N。不断地在两者之间来回跳动,直到其中之一产生具体的价值为止。
所述unamb包用途并发(和unsafePerformIO),如chepner的回答来描述实现与该平行原语or可以被定义。
parOr :: Bool -> Bool -> Bool
parOr x y = (x || y) `unamb` (y || x) -- unamb from Data.Unamb
Run Code Online (Sandbox Code Playgroud)