2013-03-07 2 views
2

Это часть программы Haskell Я был назначен для отладки:В Haskell, что может `this @ (Sentence string _) = do` означает?

process :: Sentence -> IO() 
process [email protected](Sentence string _) = do 
    render string 
    render "==>" 
    render $ translate this 

render = putStrLn 

data Sentence = Sentence String Task 

translate :: Sentence -> String  ; Incomplete Definition 
translate (Sentence string task) 
    | ... 

    | ... 

    | ... 

    | ... 

только часть этой программы я не понимаю, или признать это линия process [email protected](Sentence string _) = do Я никогда не видел раньше и [email protected] Я также не уверен, что означает подчеркивание в (Sentence string _).

ответ

7

[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 во второй раз, но, надеюсь, это иллюстрирует разницу.

+0

Вы говорите, что мне нужно добавить условие после этого оператора @, чтобы поймать несогласованный вход? – CodyBugstein

+2

Обратите внимание, что это традиционно называется «как шаблон», но идея, которую некоторые люди называют «at-pattern», не удивительна. –

+0

@ ThomasM.DuBuisson Вы абсолютно правы, и я действительно должен был знать, сколько раз я смотрел на узлы AST для шаблонов: P – DarkOtter

4

@ определяет as pattern, который позволяет вам указывать совпадающую вещь. В этом случае this - это имя, присвоенное значению Sentence.

4

Sentence быть конструктор, который принимает String и Task, в структуре [email protected](Sentence string _), this является as pattern, что имена целого предложения, string названия идет Приговор-х String, и подчеркивание где Task иначе были бы названы, по сути говоря, что Task следует игнорировать там.

+0

Очень полезная ссылка! Спасибо – CodyBugstein

+0

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

Смежные вопросы