[email protected]
является примером «как шаблон», тогда как _
является примером шаблона дикой карты. Образец wild-card используется, когда нам не важно, какое значение находится в этой точке шаблона, поэтому _
в шаблоне будет соответствовать чему угодно, и он не связывает локальные имена/переменные.
С другой стороны, мы используем шаблон as, когда мы хотим связать дополнительное локальное имя/переменную, а также сопоставлять с ним. Можно считать, что
process [email protected](Sentence string _) = ...
примерно эквивалентен
process this = let (Sentence string _) = this
in ...
Он связывает дополнительное имя, данное слева от @
знака к значению независимо от его соответствия. Сам шаблон соответствует всем, но внутренний шаблон в правой части знака @
также сопоставляется с тем, что он соответствует, и этот шаблон может не соответствовать всем, в этом случае он соответствует только конструктору Sentence
.
Из-за этого версия шаблона и версия с привязкой let имеют различное поведение, если совпадение шаблона в привязке let может завершиться неудачно, поэтому часто бывает предпочтительным, когда мы определяем несколько случаев для функции, так как он позволяет внутреннему шаблону также влиять на то, какой случай функции вызывается. Например
safeHead xs = let (x:_) = xs in Just x
safeHead [] = Nothing
потерпит неудачу при вызове с []
, как шаблоном матч xs
для первого аргумента завершается успешно, так что первый случай функции называется, а затем xs
не может быть сопоставлен с (x:_)
. Однако, если мы написали это с как образец:
safeHead [email protected](x:_) = Just x
safeHead [] = Nothing
Вызов с []
будет работать нормально, потому что внутренняя структура также проверяется, прежде чем мы решили использовать первый случай функции, и поэтому, хотя xs
матчей против []
, (x:_)
также сопоставляется с []
, который не работает, и поэтому вызывается второй случай.Я понимаю, что это довольно глупый пример, тем более что мы не используем xs во второй раз, но, надеюсь, это иллюстрирует разницу.
Вы говорите, что мне нужно добавить условие после этого оператора @, чтобы поймать несогласованный вход? – CodyBugstein
Обратите внимание, что это традиционно называется «как шаблон», но идея, которую некоторые люди называют «at-pattern», не удивительна. –
@ ThomasM.DuBuisson Вы абсолютно правы, и я действительно должен был знать, сколько раз я смотрел на узлы AST для шаблонов: P – DarkOtter