View patterns vs. pattern guards

haskell, pattern-matching

Solution

View patterns have significant overlap with pattern guards. The main advantage of view patterns is that they can be nested, and avoid introducing intermediate pattern variables. For a silly example:

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

The pattern guard equivalent requires every new view to bind a new pattern variable, alternating between evaluating expressions and binding patterns.

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

View patterns can also use only those variables bound earlier in the pattern, but it does look nice:

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

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

The main advantage of pattern guards is that they are a simple generalisation of guards, and can include ordinary Boolean expressions. I generally prefer them over view patterns because I find the style of `case` and guards less repetitious than the equational style.

Problem

I'm trying to get a sense of the relationship between view patterns and pattern guards in GHC. Pattern guards seem quite intuitive, while view patterns seem a bit confusing. It kind of looks like view patterns are better for dealing with things deep in a pattern, while pattern guards can reuse a view more intuitively, but I don't quite get it.

Original source