Чтобы помочь вам увидеть, что происходит, вы можете написать внутренние совпадающие узлы для именования левого и правого поддеревьев и их соответствующих значений с помощью
size (N _ left@(N a _ _) right@(N b _ _)) = 1 + size left + size right
Раздел 3.17.1 «Шаблоны» описывает, что происходит с символами at, которые позволяют программисту называть левое и правое поддеревья.
Шаблоны вида var@pat
называются as-pattern и разрешить использовать var в качестве имени для сопоставляемого значения: pat .
. Широкий подход неэлегатен по ряду причин.
left
и right
уже ограничены типом Tree
из-за объявления Tree
алгебраического типа данных. - Гораздо хуже, вы бытакже необходимо определить три других случая
size
для одного или двух Nil
аргументов.
Раздел 3.17.2 Неофициальная семантика сопоставления с образцом описывает случаи длякак язык обрабатывает шаблоны.Особого внимания вам в контексте этого вопроса заслуживают
1.Сопоставление шаблона var со значением v всегда завершается успешно и связывает var с v .
и
5.Сопоставление шаблона con pat 1 … pat n со значением, где con - конструктор, определенный data
, зависит отзначение:
- Если значение имеет вид con v 1 … v n , подшаблоны сопоставляются слева-право против компонентов значения данных;если все совпадения успешны, общее совпадение успешно;первый сбой или расхождение приводят к сбою или расхождению общего совпадения соответственно.
- Если значение имеет вид con ′ v 1 … v n , где con - это конструктор, отличный от con ′ , сопоставление не выполняется.
- Если значение равно ⊥, совпадение расходится.
Во-первых, как вы хотите это сделать и как вы написали это в своем вопросе, привязав левое и правое поддерево к переменным.Ваша первая попытка выглядела неопределенно как привязка к конструктору, и поэтому вы получили синтаксическую ошибку.
Сравнение с шаблоном Haskell может быть более сложным, например , просмотр шаблонов ,Для изучения упражнений сначала освоите основы.