为什么拼写错误 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)
如果按下鼠标按钮,下面的 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)