问题
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.
回答1:
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.
回答2:
View patterns let you project a value before pattern matching on it. It can almost be thought of as a short cut for
foo x = case f x of
...
There's a bit of sugar on top for dealing with more complex views, but basically that's it. On the other hand, pattern guards are strictly more general,
- They can include arbitrary boolean conditions for matching
- They can match using more than one of the variables
I favor view patterns when I'm doing something "lens-like". I have a big piece of data and I'm interested in one particular view of it. For example, with lens
foo (view someLens -> Bar baz quux) = ...
Pattern guards tend to work well when you want something closer to a more flexible case expression.
来源:https://stackoverflow.com/questions/20766841/view-patterns-vs-pattern-guards