如何显示Scala中没有构造函数的类型值会引起任何结果?我想对值进行模式匹配,并让Scala告诉我没有模式可以匹配,但是我愿意接受其他建议。这是一个为什么有用的简短示例。
在Scala中,可以在类型级别上定义自然数,例如使用Peano编码。
sealed trait Nat
sealed trait Zero extends Nat
sealed trait Succ[N <: Nat] extends Nat
由此我们可以定义一个数字为偶数的含义。零是偶数,比偶数多2的数字也是偶数。
sealed trait Even[N <: Nat]
sealed case class Base() extends Even[Zero]
sealed case class Step[N <: Nat](evenN: Even[N]) extends Even[Succ[Succ[N]]]
由此我们可以证明例如两个是偶数:
val `two is even`: Even[Succ[Succ[Zero]]] = Step(Base())
但是,即使编译器可以告诉我Base
和Step
都不能居住在该类型上,所以我无法证明那不是一个偶数。
def `one is odd`(impossible: Even[Succ[Zero]]): Nothing = impossible match {
case _: Base => ???
case _: Step[_] => ???
}
编译器会很高兴地告诉我,我给出的所有情况都不可能发生错误pattern type is incompatible with expected type
,但是将match
块留空将是编译错误。
有什么方法可以建设性地证明这一点吗?如果要使用空模式匹配-我会接受任何版本的Scala甚至是宏或插件,只要在使用该类型时我仍然会收到空模式匹配错误。也许我在说错了树,模式是否与错误的主意相吻合-EFQ是否可以通过其他方式显示?
注意:可以用另一个(但等价的)均匀度定义证明一个是奇数-但这不是重点。为何需要EFQ的简短示例:
sealed trait Bottom
def `bottom implies anything`(btm: Bottom): Any = ???
答案 0 :(得分:3)
Ex fquo quodlibet 的意思是“从矛盾出发,一切都会随之而来”。
在标准Curry-Howard编码中,Nothing
对应于
错误,因此以下简单函数实现了原理
爆炸:
def explode[A]: Nothing => A = n => n
它可以编译,因为Nothing
万能,以至于
代替任何东西(A
)。
但是,这不会为您带来任何收益,因为您的初始 假设来自
There is no proof for `X`
随之而来
There must be proof for `X => _|_`
不正确。这不仅对直觉/构造逻辑不正确,而且通常不正确:只要您的系统可以 count ,
是无法证明的真实陈述,因此在每一个一致的陈述中
带有Peano Naturals的系统,必须有一些声明X
这样X
不能被Goedel证明,以及它们的否定
X => _|_
也无法证明(一致性)。
似乎您在这里需要的是某种“反转引理”(在Pierce的“类型和编程语言”的意义上),它限制了构造某些类型的术语的方式,但是我不知道在Scala的类型系统中看不到任何可以为您提供这种引理的类型级别编码的东西。
答案 1 :(得分:3)
对于Scala中的任意无人居住类型,可能无法证明 configure<CrashlyticsExtension> {
betaDistributionReleaseNotes = "xxx"
}
,但仍然有可能证明ex falso
。我的证明只需要对您的Even[Succ[Zero]] => Nothing
定义进行少量修改即可解决Scala中缺少的功能。在这里:
Nat