головные и хвостовые вызовы в пустом списке с исключением - PullRequest
3 голосов
/ 22 августа 2010

Я следую учебному пособию.(Real World Haskell)

И у меня есть один вопрос новичка о голове и хвосте, вызываемый в пустых списках: в GHCi он возвращает исключение.

Интуитивно я думаю, что я бы сказал, что они оба должны вернуть пустоесписок.Не могли бы вы исправить меня?Почему бы и нет ?(насколько я помню, в OzML слева или справа от пустого списка возвращается ноль)

Я, конечно, еще не рассматривал эту тему в руководстве, но не является ли это источником ошибок (если не приводить аргументов)?Я имею в виду, если когда-нибудь передача функции списка аргументов, которые могут быть необязательными, чтение их головой может привести к ошибке?

Я просто знаю поведение GHCi, я не знаю, что происходит при компиляции.

1 Ответ

13 голосов
/ 22 августа 2010

Интуитивно я думаю, что они оба должны возвращать пустой список.Не могли бы вы исправить меня?Почему бы и нет?

Ну - head - это [a] -> a.Возвращает единственный, первый элемент;нет списка.

А когда нет первого элемента, как в пустом списке?Ну что вернуть?Вы не можете создать значение типа a из ничего, поэтому остается только undefined - ошибка.

И tail?Хвост, по сути, представляет собой список без первого элемента, т.е. на один элемент короче исходного.Вы не можете соблюдать эти законы, когда нет первого элемента.

Когда вы достаете одно яблоко из коробки, у вас не может быть такого же ящика (что случилось, когда tail [] == []).Поведение должно быть undefined тоже.


Это приводит к следующему выводу:

Я, конечно, еще не рассматривал эту тему в учебнике, но это не такисточник ошибок?Я имею в виду, что если когда-нибудь передать функции список аргументов, которые могут быть необязательными, чтение их с головой может привести к ошибке?

Да, это источник ошибок, но потому что он позволяетнаписать некорректный код.Код, который в основном пытается прочитать значение, которое не существует.Итак: * Никогда не используйте голову / хвост ** - Используйте сопоставление с образцом.

sum     [] = 0
sum (x:xs) = x + sum xs

Компилятор может гарантировать , что все возможные случаи покрыты, значения всегда определены, и этонамного чище читать.

...