2

下面的 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)

这种行为的原因是一个简单的拼写错误——如果你trueTruefalse替换False,一切都按预期工作。

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

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

4

1 回答 1

2

我必须研究为什么 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)
于 2015-03-15T08:16:20.230 回答