Имеет ли значение порядок определения функции в шаблонах списков - PullRequest
5 голосов
/ 27 апреля 2020

Таким образом, эти порядки функций имеют различное поведение в GHCI:

safetailpatter xs = tail xs
safetailpatter [] = []
safetailpatter [] = []
safetailpatter xs = tail xs

Первый формирует следующее предупреждение и следующую ошибку при передаче []

ex3.hs:66:1: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In an equation for ‘safetailpatter’: safetailpatter [] = ...
*** Exception: Prelude.tail: empty list

Как таковой порядок определения и почему? Я не понимаю, почему первое совпадает, а второе не совпадает с определением.

Ответы [ 2 ]

8 голосов
/ 27 апреля 2020

xs также соответствует пустому списку, поэтому safetailpatter [] никогда не будет вызываться, если вы поставите safetailpatter xs первым.

Я довольно новичок в Haskell, но я думаю, что это то, что происходит.

Итак, когда вы сначала помещаете safetailpatter xs, а затем вызываете его с пустым списком, вы пытаетесь вызвать tail в пустом списке, и вы получаете исключение.

Что касается

Pattern match is redundant
    In an equation for ‘safetailpatter’: safetailpatter [] = ...

Я думаю, что это в основном означает то, что я описал выше, жалуется, что объявление является избыточным, потому что safetailpatter [] уже покрыто safetailpatter xs, когда вы ставите последнее первым.

По этой причине вы всегда должны ставить _ в конце определений соответствия шаблону, иначе вам не будут вызываться остальные шаблоны:

myF (x:xs) = -- ....
myF _ = -- ...        -> Right
myF _ = -- ...        -> Wrong, now no the bellow definition will never get called
myF (x:xs) = -- ....
7 голосов
/ 27 апреля 2020

Шаблоны подбираются по порядку. Но здесь происходит то, что вы на самом деле не совпадаете с партией на safetailpatter xs.

В обычном английском языке sh safetailpatter xs = tail xs означает: safetailpatter для любой переменной является хвостом этой переменной .

То, что вы хотите сопоставить: safetailpatter (x:xs) = tail (x:xs), 1012 * Зная это, в коде

safetailpatter xs = tail xs
safetailpatter [] = []

Will будет означать: *1010* safetailpatter при применении к списку хотя бы с одним элементом. проверьте по порядку, и поскольку первое уравнение соответствует любому входному списку, вы получите ошибку времени выполнения на []. Принимая во внимание, что

safetailpatter (x:xs) = tail xs
safetailpatter [] = []

совпадает по порядку, а поскольку [] не соответствует первому уравнению, оно будет выполняться второе без ошибок времени выполнения

Редактировать

Как говорит @chepner, это вызов неопровержимый шаблон . Это означает, что сопоставление с образцом происходит, но шансов на неудачу нет. То же, что если вы играете против _

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...