为什么拼写错误 true/false 不会在在线 Elm 编辑器(与 elm-repl 相对)中引发编译器错误?

Why does mis-spelling true/false not raise a compiler error in the online Elm editor (as opposed to elm-repl)?

如果按下鼠标按钮,下面的 Elm 程序应该打印 10,如果没有按下则打印 20,但它总是打印 20(当 运行 它位于 http://elm-lang.org/try 时):

import Mouse
import Text (asText)
import Signal (map)


nextVal : Bool -> Int
nextVal down = 
  case down of
    true -> 10
    false -> 20


main = map asText (map nextVal Mouse.isDown)

此行为的原因是一个简单的拼写错误 - 如果您将 true 替换为 True 并将 false 替换为 False,一切都会按预期进行。

但是为什么我没有收到编译器错误呢?我本以为会出现类似于我从 elm-repl 收到的错误消息:Could not find variable 'true'

更新 事实上(正如@Apanatshka 在回答中暗示的那样),此代码也适用于 REPL,因此 Elm 的行为始终如一。

我必须调查为什么 elm-repl 会出现该错误。

当我在 elm-lang.org/try 上尝试此代码时,它总是给出 10。您提供的代码是有效的 Elm 代码。当您在 case-of 模式中写入小写名称时,该名称被视为模式变量。它将匹配任何内容并将匹配的内容绑定到该名称。因此,您的 nextVal 函数将尝试按照给定的顺序将布尔值与给定的模式匹配。它从第一个模式开始,这是一个单一的模式变量,因此它总是匹配。它在那里停止搜索,因为模式匹配,因此总是返回 10。

也许您更愿意使用 if-then-else

nextVal down =
  if down
    then 10
    else 20

最后一件事:当您只是匹配像 Bool 这样的枚举时,这些模式变量似乎没有用。只是为了证明它是有用的,我用一个单链表写了一个小例子:

type SLList a =
  Cons a (SLList a)
  | Nil
-- a list of 1,2,3 would look like: Cons 1 (Cons 2 (Cons 3 Nil))

removeSurroundingElements : SLList a -> SLList a
removeSurroundingElements l = 
  case l of
    Nil -> Nil
    Cons _ Nil -> l -- `_` means ignore
    Cons _ (Cons _ Nil) -> l
    Cons e1 (Cons e2 (Cons e3 tail)) ->
      Cons e2 (removeSurroundingElements tail)
-- removeSurroundingElements (Cons 1 (Cons 2 (Cons 3 Nil))) == Cons 2 Nil
-- removeSurroundingElements (Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 (Cons 6 Nil))))))
--   == Cons 2 (Cons 5 Nil)