Entry tags:
View patterns
Наконец то! SPJ предлагает добавить views patterns в Haskell'.
Views patterns - это не совсем views, вернее, совсем не views :-) Это, скорее, другая форма записи pattern guards - более легкая и почти элегантная ;-) Здесь SPJ ещё в далёком 97-м рассматривал pattern guards как альтернативу views.
Мой интерес к views растёт с одной задачи, которую рассматривали мы с
thesz. Ниже я описал pattern guards как раз на её примере.
Для тех, кто не в курсе насчет views и pattern guards я попытаюсь объяснить задачи, которые они решают. Вернее, какую пользу от них вижу я :-)
Механизм паттерн матчинга очень удобен при декларативном описании - его лаконичность и однозначность делают код более простым и понятным. Однако, он использует внутреннее представление типа и, следовательно, типы, потроха которых скрыты от их пользователя, несовместимы с механизмом паттерн матчинга. Зачем нужны такие типы, думаю, понятно. По сути, причина одна - это сокрытие реализации и предоставление интерфейса работы со значениями типа с целью задания ограничений на работу с типом. Модульность, инкапсуляция и всё такое.
Разумеется, очень хотелось бы, несмотря на заявленные ограничения, воспользоваться паттерн матчингом. Так вот, для того, чтобы значение типа можно было сравнить с неким образцом (паттерном), необходимо это значение представить в виде другого значения, которое мы уже можем сравнить. Это "другое" значение называется view.
В view pattern эта проблема решается так. Допустим, у нас есть тип очереди
и функция для перевода очереди в список:
Предположим, мы хотим узнать, содержат ли первые пять значений единички. Для списка это паттерн 1:1:1:1:1:_. С помощью view patterns это запишется так:
Зачем здесь Just? Дело в том, что view pattern записывается в виде (expr -< pattern), где expr - обычное выражение Haskell, а pattern - соответственно, образец, с которым сравниваем view. Правила сравнения просты:
Вот и всё. Остальное в Trac'е.
Views patterns - это не совсем views, вернее, совсем не views :-) Это, скорее, другая форма записи pattern guards - более легкая и почти элегантная ;-) Здесь SPJ ещё в далёком 97-м рассматривал pattern guards как альтернативу views.
Мой интерес к views растёт с одной задачи, которую рассматривали мы с
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Для тех, кто не в курсе насчет 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'е.