为什么在Haskell案例语句中默认的catch all不是强制性的?

为什么在Haskell案例语句中默认的catch all不是强制性的?,haskell,Haskell,哈斯克尔以安全的语言著称。一般来说,将更多可能的编程错误推到编译时错误,而将更少的编程错误推到运行时错误 其中一个例子是if表达式。if中的else始终是必需的。你需要掩盖这两种可能性。这很好,因为您已经考虑并排除了运行时发生的所有可能性 现在Haskell有了一个case表达式。(这与其他OO和命令式语言中的switch语句有一些相似之处,但Haskell在类型系统中增加了很多内容) 但是对于case表达式,默认的“catch all”不是必需的 对我来说,这听起来像是会导致运行时错误 我的问

哈斯克尔以安全的语言著称。一般来说,将更多可能的编程错误推到编译时错误,而将更少的编程错误推到运行时错误

其中一个例子是
if
表达式。if中的
else
始终是必需的。你需要掩盖这两种可能性。这很好,因为您已经考虑并排除了运行时发生的所有可能性

现在Haskell有了一个
case
表达式。(这与其他OO和命令式语言中的
switch
语句有一些相似之处,但Haskell在类型系统中增加了很多内容)

但是对于
case
表达式,默认的“catch all”不是必需的

对我来说,这听起来像是会导致运行时错误


我的问题是:为什么在Haskell
案例中默认的catch-all不是强制性的?

并非总是需要catch-all。如果显式地处理所有情况(模式匹配是穷举的),则永远不会达到“一网打尽”的情况

我可以想到一个强制性的“包罗万象”的严重缺点:如果扩展了ADT(代数数据类型),依赖代码仍然会编译,程序员不会被提醒他们应该处理的额外情况。

Haskell肯定比许多其他语言更安全,尤其是主流语言,但它远不是100%安全的。Haskell中的其他不安全功能包括编写无限循环的能力,如
让x=x在x中
,或
未安全性能
,或
错误
,或
未定义
。我想你可以说这只是方便和安全之间的折衷

在比简单示例更复杂的代码中,有时会出现一些您知道不可能出现的情况,因此您将它们从
case
表达式中删除,但Haskell的类型系统不够强大,编译器无法知道这些缺失的情况是不可能发生的。(例如,您可能正在计算一些只能返回数字
3
4
5
的数学函数,但这是由于某些您碰巧知道但编译器不知道的困难定理造成的。)


如果愿意,您可以将
-fwarn completed patterns
传递给
ghc
编译器,以便在编译时在case语句中丢失分支时获得警告。这包括在
-W
选项中,该选项会打开一些常见的编译器警告。

您可以编写
\uux>错误“永远不会发生”
,但这是默认行为。重点是什么?您的上一个模式
xs->“…”
已经是一个包罗万象的问题了-为什么您没有被强制使用
,或者这是为什么当您不匹配所有模式时得到的警告不是错误?一个更好的问题可能是:为什么Haskell中的模式匹配不能是无遗漏的?因为如果一个人明确地涵盖了所有的情况,那么“包罗万象”将是超级的,甚至是有害的。如果你想要100%的安全,就使用类似Coq的东西。对于这种情况,它会给您一个编译错误,因为Coq中的所有内容都必须定义,所有计算都必须停止。这是以使语言非图灵完整为代价的,并为程序编写者提供终止证明等方面增加了相当多的负担@n.m.我想这是品味的问题。就个人而言,我希望非穷尽性在默认情况下是编译时错误,除非使用catch-all分支显式地延迟到运行时。如果我有一个关于不完整模式的
-Werror
我会打开它(
-Werror
对我来说太过分了)。是的-但这是一个评论,并没有真正回答我不同意的问题-这个答案提供了一个可能的解释,解释了为什么“一刀切”案例不是强制性的,通过解释一种方式,如果该语言是强制性的,那么它将更难正确使用。听起来像是对我的回答。这回答了OP的问题,但我不知道它是否回答了OP想要问的问题。我不确定这里的实际问题是否是“为什么允许非穷举模式?”。是的@chi,我也写了一篇评论。提出的问题很容易引起误解。另一个可能的答案是:GADT使(声音和完整的)穷尽性检查不可判定。同样正确!虽然我认为在哈斯凯尔案中,当决定不对案例陈述进行详尽检查时,GADT并不存在。但不要忘记,
-Werror
可以有效地将警告转化为错误,正如OP所要求的那样。
describeList :: [a]
describeList xs = "The list is " ++ case cs of [] -> "empty."
                                               [x] -> "a singleton list."
                                               xs -> "a longer list."