Patterns are not just for function definitions. Patterns can be used anywhere a name is being bound to a value. Another way to put this is, anyplace you see a name being bound to a value, the name can be replaced by a pattern that decomposes the value. In the following expression, the name z is bound to a literal list value. let z = [10, 11, 12, 13, 14, 15] in [head (tail z)]++(tail (tail (tail z))++[head (tail (tail z))] The above expression is nearly impossible to read. Here it is with the name z replaced by a pattern that decomposes the list value. let (_:x:y:ys) = [10, 11, 12, 13, 14, 15] in [x]++ys++[y] In the following expression, the name z is bound to the return value from tail. let z = tail [21, 22, 23, 24, 25, 26] in (head z, tail z) Here is an equivalent expression with the name z replaced by a pattern that decomposes the return value. let (x:xs) = tail [21, 22, 23, 24, 25, 26] in (x,xs) Notice the subtle difference between (x:x) and (x,xs) In the following expression, the name z is bound to values taken from a list. [(snd z, fst z) | z<-[(1,2), (2,3), (3,4), (5,6)]] Here is a more readable version of this expression with z replaced by a pattern that decomposes the values taken from the list. [(y,x) | (x,y)<-[(1,2), (2,3), (3,4), (5,6)]] How would you rewrite the following example without using a pattern to decompose the values taken from the list? [(y,x) | (x,_,y)<-[(1,0,2), (2,0,3), (3,0,4), (5,0,6)]] (Ans: With great difficulty.) Here is an example of a pattern used in a list comprehension where the failure of the pattern to match a value is used as a way to filter out values from a list. Notice that failure to match a pattern need not be an error. The list comprehension just skips over the values that don't match. [y | (1,y)<-[(1,2), (2,3), (3,4), (2,5), (1,6)]] Look at the next two examples. Here, the "failure" to match the pattern is actually not a pattern matching failure, it is a type error. The "type" of the pattern does not agree with the type of the value. [(y,x) | (x,y)<-[(1,0,2), (2,0,3), (3,0,4), (5,0,6)]] [(y,x) | (x,y,z)<-[(1,2), (2,3), (3,4), (5,6)]] Here is a final, very important, example. How many patterns are used in the following expression? What value is each pattern decomposing? let (u,v) = f [2,4..10] in u + v where f (x:y:ys) = (x,y) Here is a version of the above expression written without any patterns. let z = f [2,4..10] in (fst z) + (snd z) where f z = (head z, head (tail z)) How readable is that?