lomeo: (лямбда)
Dmitry Antonyuk ([personal profile] lomeo) wrote2007-01-23 01:20 pm

View patterns

Наконец то! SPJ предлагает добавить views patterns в Haskell'.

Views patterns - это не совсем views, вернее, совсем не views :-) Это, скорее, другая форма записи pattern guards - более легкая и почти элегантная ;-) Здесь SPJ ещё в далёком 97-м рассматривал pattern guards как альтернативу views.

Мой интерес к views растёт с одной задачи, которую рассматривали мы с [livejournal.com profile] thesz. Ниже я описал pattern guards как раз на её примере.


Для тех, кто не в курсе насчет views и pattern guards я попытаюсь объяснить задачи, которые они решают. Вернее, какую пользу от них вижу я :-)

Механизм паттерн матчинга очень удобен при декларативном описании - его лаконичность и однозначность делают код более простым и понятным. Однако, он использует внутреннее представление типа и, следовательно, типы, потроха которых скрыты от их пользователя, несовместимы с механизмом паттерн матчинга. Зачем нужны такие типы, думаю, понятно. По сути, причина одна - это сокрытие реализации и предоставление интерфейса работы со значениями типа с целью задания ограничений на работу с типом. Модульность, инкапсуляция и всё такое.

Разумеется, очень хотелось бы, несмотря на заявленные ограничения, воспользоваться паттерн матчингом. Так вот, для того, чтобы значение типа можно было сравнить с неким образцом (паттерном), необходимо это значение представить в виде другого значения, которое мы уже можем сравнить. Это "другое" значение называется view.

В view pattern эта проблема решается так. Допустим, у нас есть тип очереди

data Queue a = ...


и функция для перевода очереди в список:

queueToList :: Queue a -> [a]


Предположим, мы хотим узнать, содержат ли первые пять значений единички. Для списка это паттерн 1:1:1:1:1:_. С помощью view patterns это запишется так:

fiveOnes :: Queue Integer -> Bool
fiveOnes (Just . queueToList -> 1:1:1:1:1:_) = True
fiveOnes _ = False


Зачем здесь Just? Дело в том, что view pattern записывается в виде (expr -< pattern), где expr - обычное выражение Haskell, а pattern - соответственно, образец, с которым сравниваем view. Правила сравнения просты:


  • Считаем (expr v). В нашем примере - считаем (Just . queueToList) query.

  • Если результат Nothing - то считаем попытку неудачной.

  • Если результат Just x - то сравниваем x с образцом pattern.



Вот и всё. Остальное в Trac'е.


Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting