为什么要从 Elm 中删除 case guards?

Why were case guards removed from Elm?

其他函数式编程语言也有这个特性,比如OCaml:

match x with
| Some n when n < 10 -> ...
| Some n when n < 100 -> ...
...

或Haskell:

case x of 
  Just n | n < 10 -> ...
         | n < 100 -> ...
  ...

为什么从 Elm 中删除它? (早期版本显然有它。)
在 Elm 中表达相同内容的惯用方式是什么?

使用 if 表达式。无论如何,这真的是所有守卫:

case x of 
  _ ->
    if x > 10 then
      ...
    else
      ...

在某些情况下,这确实会导致重复的 else 分支,否则这些分支可能会被单个 _ 分支覆盖。对此的解决方案与在其他任何地方重用代码相同:使用函数:

let 
  default = ...
in
case x of
  Some y ->
    if y > 10 then
      ...
    else
      default
  _ ->
    default

(注意这里的default会被严格求值,如果计算量很大,添加()作为伪参数来懒惰求值。)

为什么删除了它?好吧,我无法像你一样读懂 Evan 的想法,但我的猜测是因为它使 case 表达式的语法和语义都变得复杂。

例如,对于初学者来说,一个常见的错误是当编译器抱怨 case 表达式并不详尽时,他们为 do[=] 提供的守卫分支感到困惑39=] 涵盖所有情况:

case x of 
  _ | x < 10 -> ...
  _ | x >= 10 -> ...
-- Error: This `case` does not have branches for all possibilities
-- Why u do dis, compiler?

静态模式与穷举检查和可以使用变量和运算符的动态保护表达式的混合使许多初学者感到非常困惑。许多人还使用带有守卫的 case 表达式而不是 any if 表达式,只是因为 case "feels more functional".

因此没有守卫使得语言更容易学习并且仍然同样有能力,代价是在一些相对罕见的情况下稍微更冗长。