Сопоставление шаблона со звездой Клини по типу структуры в Racket

Недавно я начал играть с системой сопоставления шаблонов Racket и столкнулся с проблемой, которую не могу понять.

If i do:

(match (list 1 2 3 4 5 6 7 8 9 10 11 12)
    [(list _ x y z ...) (list y ': x)]) 

в REPL я получаю

'(3 : 2)

как мой желаемый результат.

If i do:

(match (current-date)
    [(date* _ x y z ...) (list y ': x)])

or

(match (date* 5 18 13 18 11 2011 5 321 #f 3600 0 "W. Europe Standard Time")
    [(date* _ x y z ...) (list y ': x)])

я получаю эту ошибку:

match: wrong number for fields for structure date*: expected 12 but got 5 in: (_ x y z ...)

я подозреваю, что звезда Клини ... по какой-то причине не работает со структурным типом. Почему это так?


person mentus    schedule 18.11.2011    source источник


Ответы (2)


Кажется, что вы действительно хотите сопоставить подмножество полей в структуре, а не привязывать остальные поля в структуре к (z...). В этом случае вы можете попробовать использовать struct* соответствует шаблону.

Вот пример:

(match (date* 5 18 13 18 11 2011 5 321 #f 3600 0 "W. Europe Standard Time")
   [(struct* date ([minute x] [hour y])) (list y ': x)])
person Asumu Takikawa    schedule 18.11.2011
comment
@ruakh ваш ответ описывает, почему это не работает. Этот ответ описывает как заставить его работать. Оба весьма полезны. - person Dan Burton; 19.11.2011
comment
Да, оба полезны. Спасибо. - person mentus; 25.11.2011

я подозреваю, что звезда Клини ... по какой-то причине не работает со структурным типом.

Правильный. Обозначение ... и связанные с ним обозначения ..k, ___ и __k на самом деле не являются общим признаком сопоставления, а скорее являются специфическим признаком list-сопоставления, hash-table-сопоставления и так далее. Если вы изучите формальное производство в документации, вы увидите, что некоторые типы подшаблонов принимают lvp ( который определяется как pat или pat, за которым следует ... или один из его друзей) в разных местах, тогда как другие принимают только pat.

Почему это так?

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

person ruakh    schedule 18.11.2011