Просмотр шаблонов против шаблонов

Я пытаюсь понять взаимосвязь между шаблонами взглядов и защитой шаблонов в GHC. Шаблоны охранников кажутся довольно интуитивными, в то время как шаблоны представления кажутся немного запутанными. Это похоже на то, что шаблоны просмотра лучше подходят для работы с вещами глубоко в шаблоне, в то время как защитники шаблонов могут повторно использовать представление более интуитивно, но я не совсем понимаю его.

Ответ 1

Представленные шаблоны имеют значительное совпадение с защитой шаблонов. Основное преимущество шаблонов представлений заключается в том, что они могут быть вложенными и избегать введения промежуточных переменных шаблона. Для глупых примеров:

endpoints (sort -> begin : (reverse -> end : _)) = Just (begin, end)
endpoints _ = Nothing

Эквивалент защиты шаблона требует, чтобы каждое новое представление связывало новую переменную шаблона, чередуя между оценкой выражений и шаблонами привязки.

endpoints xs
  | begin : sorted <- sort xs
  , end : _ <- reverse sorted
  = Just (begin, end)
  | otherwise = Nothing

В шаблонах просмотра также могут использоваться только те переменные, которые были связаны ранее в шаблоне, но он выглядит хорошо:

nonzero :: (a -> Int) -> a -> Maybe a
nonzero f (f -> 0) = Nothing
nonzero _ x = Just x

-- nonzero (fromEnum . not . null) "123" == Just "123"
--                                 ""    == Nothing

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

Ответ 2

Просмотр шаблонов позволяет проецировать значение до его соответствия шаблону. Его можно почти рассматривать как короткий отрезок для

 foo x = case f x of
   ...

Там немного сахара на вершине для работы с более сложными видами, но в основном это. С другой стороны, шаблоны ограждений строго более общие,

  • Они могут включать произвольные логические условия для сопоставления
  • Они могут соответствовать более чем одной из переменных

Я предпочитаю шаблоны просмотра, когда я делаю что-то "линзоподобное". У меня есть большой объем данных, и меня интересует один конкретный взгляд на него. Например, с объективом

foo (view someLens -> Bar baz quux) = ...

Защитники шаблонов, как правило, хорошо работают, когда вы хотите что-то ближе к более гибкому выражению case.