View patterns
Jan. 23rd, 2007 01:20 pmНаконец то! 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 растёт с одной задачи, которую рассматривали мы с
Для тех, кто не в курсе насчет 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'е.
no subject
Date: 2007-01-24 03:51 pm (UTC)no subject
Date: 2007-01-24 04:10 pm (UTC)Проблема возникает в случае, когда для значения типа нет конкретного представляения в другом типе.
Это IMHO, разумеется.
Да! Основное отличие pattern guards от view patterns это не то, что писать меньше, а то, что views могут быть вложенными, т.к. это не гарды, а паттерн (это я не сам догадался - с хаскель мейллиста прочел)
no subject
Date: 2007-01-24 04:18 pm (UTC)no subject
Date: 2007-01-24 04:25 pm (UTC)Мою фразу "Для проверки содержания единиц в начале достаточно пользоваться view без Maybe обертки." стоит расценивать только как "было бы достаточно, если бы это позволялось" ;-)
no subject
Date: 2007-01-24 04:46 pm (UTC)no subject
Date: 2007-01-24 05:47 pm (UTC)no subject
Date: 2007-01-24 08:11 pm (UTC)