Ign*_*rov 5 recursion logic haskell paradox curry-howard
Curry的悖论 (以与当前编程语言相同的人命名)是一种错误逻辑的构造,它允许人们证明任何东西。
我对逻辑一无所知,但是有多难?
module Main where
import Data.Void
import Data.Function
data X = X (X -> Void)
x :: X
x = fix \(X f) -> X f
u :: Void
u = let (X f) = x in f x
main :: IO ()
main = u `seq` print "Done!"
Run Code Online (Sandbox Code Playgroud)
它肯定会循环。(GHC如何知道?!)
% ghc -XBlockArguments Z.hs && ./Z
[1 of 1] Compiling Main ( Z.hs, Z.o )
Linking Z ...
Z: <<loop>>
Run Code Online (Sandbox Code Playgroud)
fix
递归的情况下做同样的事情吗?为什么?库里悖论的编码看起来更像是这样的:
x :: X
x = X (\x'@(X f) -> f x')
Run Code Online (Sandbox Code Playgroud)
X
确实可以理解为“如果X
为真,则存在矛盾”这句话,或者等效地,“X
为假”。
但用fix
证明来证明X
并没有什么实际意义,因为fix
作为推理原则是明显错误的。库里的悖论更加微妙。
你实际上如何证明X
?
x :: X
x = _
Run Code Online (Sandbox Code Playgroud)
X
是一个条件命题,所以你可以先假设它的前提来得出它的结论。此逻辑步骤对应于插入 lambda。(建设性地,蕴涵的证明是从前提证明到结论证明的映射。)
x :: X
x = X (\x' -> _)
Run Code Online (Sandbox Code Playgroud)
但现在我们有了一个假设x' :: X
,我们可以再次展开 的定义X
得到f :: X -> Void
。在 Curry 悖论的非正式描述中,没有明确的“展开步骤”,但在 Haskell 中,它对应于 newtype 构造函数上的模式匹配 whenX
是假设,或者应用构造函数 whenX
是目标(事实上,正如我们上面所做的那样) ):
x :: X
x = X (\x'@(X f) -> _)
Run Code Online (Sandbox Code Playgroud)
最后,我们现在有了f :: X -> Void
和x' :: X
,因此我们可以Void
通过函数应用推导出:
x :: X
x = X (\x'@(X f) -> f x')
Run Code Online (Sandbox Code Playgroud)