Haskell列表推导中模式匹配失败的原理及示例咨询
Hey there! Let's break this down with concrete examples so you can see exactly what "pattern matching failure" means and when it happens in list comprehensions.
First, a quick recap: In Haskell list comprehensions, when you use a pattern to match elements from a list, if an element doesn't fit that pattern, we call this a pattern matching failure. Instead of throwing an error, the list comprehension just skips that element entirely—it won't show up in your final result list.
Let's look at common scenarios with examples:
1. Matching Specific Tuple Patterns
Suppose we have a list of (Int, String) tuples, and we only want to extract the string from tuples where the first element is exactly 3:
myTuples = [(1, "a"), (3, "b"), (2, "c"), (3, "d")] result = [str | (3, str) <- myTuples]
- When the comprehension hits
(1, "a"), the pattern(3, str)doesn't match (since the first element is 1, not 3)—this is a matching failure, so the element is skipped. (3, "b")matches perfectly, so"b"is added toresult.(2, "c")fails the pattern match and is skipped.(3, "d")matches, so"d"is added.
The final result will be ["b", "d"]—the elements that failed to match are nowhere to be seen.
2. Matching List Length/Structure Patterns
List patterns let us match based on how a list is structured. For example, let's say we want the first element of every sublist that has at least two elements:
myLists = [[1,2], [], [3,4,5], [], [6]] result = [first | (first:second:_) <- myLists]
The pattern (first:second:_) requires the list to have at least two elements (since we're matching the first two items, plus the rest). Here's what happens:
[1,2]matches, so1is added toresult.[](empty list) can't match the pattern—failure, skipped.[3,4,5]matches, so3is added.[]fails again, skipped.[6]only has one element, so it can't match the pattern—failure, skipped.
Final result is [1,3].
3. Matching Custom Data Type Patterns
If you have a custom data type, pattern matching failures work the same way. Let's define a simple Fruit type and filter for only bananas:
data Fruit = Apple String | Banana Int | Orange deriving (Show) basket = [Apple "Red", Banana 5, Orange, Apple "Green", Banana 3] bananaCounts = [count | Banana count <- basket]
Apple "Red"doesn't match theBanana countpattern—failure, skipped.Banana 5matches, so5is added.Orangedoesn't match—failure, skipped.Apple "Green"fails, skipped.Banana 3matches, so3is added.
The bananaCounts result is [5,3].
To tie this back to the book: Every time an element doesn't fit the pattern you've specified in your list comprehension, that's a pattern matching failure. Haskell just moves on to the next element instead of crashing, which is why those failed elements don't end up in your result.
内容的提问来源于stack exchange,提问作者CoreNoob

