Почему неправильное написание true/false не вызывает ошибку компиляции в онлайн-редакторе Elm (в отличие от 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
person Frank Schmitt    schedule 15.03.2015    source источник


Ответы (1)


Мне нужно выяснить, почему 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)
person Apanatshka    schedule 15.03.2015
comment
Это объяснение имеет смысл. И на самом деле, это работает и в REPL — я допустил глупую ошибку, запуская его внутри REPL. - person Frank Schmitt; 15.03.2015