Как аккуратно деконструировать новые типы, вложенные в записи?

#pattern-matching #purescript #newtype

#сопоставление с образцом #purescript #newtype

Вопрос:

Я использую newtype в качестве поля записи, а сопоставление с образцом для «родительского» типа для извлечения вложенного значения является громоздким:

 newtype CityName = CityName String
newtype City = City {
  name :: CityName
}
instance showCity :: Show City where
  show (City { name }) = case name of (CityName cn) -> "City(" <> cn <> ")"
  

Я могу деконструировать «родительский» тип, но затем я использую другое сопоставление с образцом для извлечения обернутой строки — даже если newtype имеет только один конструктор данных. Было бы удобнее деконструировать весь тип всего одним шаблоном.

Возможно ли это? Если это так, я не могу правильно использовать синтаксис. Я пробовал что-то вроде show (City { name :: (CityName cn) }) = cn , но это дает мне синтаксические ошибки. Пример PureScript мне тоже не помог, но, может быть, есть более аккуратный способ сделать то, что я хочу?

Ответ №1:

То, что вы пробовали, почти правильно, но вам нужно только одно двоеточие при сопоставлении записей с образцом:

 instance showCity :: Show City where
  show (City { name: CityName cn }) = "City(" <> cn <> ")"
  

Двойное двоеточие используется только для аннотирования типов, материал уровня значений всегда использует одно двоеточие.

Комментарии:

1. Спасибо, отличное объяснение. Этот синтаксис где-то документирован или он такой же, как в Haskell? Интересно, есть ли еще «трюки» деконструкции, о которых я не знаю.

2. Здесь есть руководство по языку на Github Wiki: github.com/purescript/purescript/wiki /. … Вероятно, это также описано в книге PureScript, но на самом деле это не ссылка, так что, возможно, это не самое простое место для поиска подобных вещей!