갈루아의 반서재

1. Pattern matching consists of 

1. specifying patterns to which some data should conform
2. checking to see if it does 
3. deconstructing the data according to those patterns

When defining functions, you can define separate function bodies for different patterns.


2. You can pattern match on any data type — numbers, characters, lists, tuples, etc. 


3. Order is important when specifying patterns and it's always best to specify the most specific ones first and then the more general ones later.

  1. factorial :: (Integral a) => a -> a  
  2. factorial 0 = 1  
  3. factorial n = n * factorial (n - 1)  


4. Pattern matching can also failWe should always include a catch-all pattern so that our program doesn't crash if we get some unexpected input.


5. Pattern matching can also be used on tuples. 

  1. addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)  
  2. addVectors a b = (fst a + fst b, snd a + snd b)  
  1. addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)  
  2. addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)  

The _ means that we really don't care what that part is, so we just write a _.

  1. first :: (a, b, c) -> a  
  2. first (x, _, _) = x  
  3.   
  4. second :: (a, b, c) -> b  
  5. second (_, y, _) = y  
  6.   
  7. third :: (a, b, c) -> c  
  8. third (_, _, z) = z  


6. Pattern match in list comprehensions.

  1. ghci> let xs = [(1,3), (4,3), (2,4), (5,3), (5,6), (3,1)]  
  2. ghci> [a+b | (a,b) <- xs]  
  3. [4,7,6,8,11,4]   

Should a pattern match fail, it will just move on to the next element.


7. Pattern match against list

Our own implementation of the head function.

  1. head' :: [a] -> a  
  2. head' [] = error "Can't call head on an empty list, dummy!"  
  3. head' (x:_) = x  

length function using list comprehension

  1. length' :: (Num b) => [a] -> b  
  2. length' [] = 0  
  3. length' (_:xs) = 1 + length' xs  

If we call length' on "ham"

1) It will check if it's an empty list

2) Because it isn't, it falls through to the second pattern. It matches on the second pattern and there it says that the length is 1 + length' "am" → 1 + (1 + length' "m")  1 + (1+(1+ length' []))    1 + (1 + (1 + 0)).

Let's implement sum.

  1. sum' :: (Num a) => [a] -> a  
  2. sum' [] = 0  
  3. sum' (x:xs) = x + sum' xs  


8. @ in front of a pattern

You do that by putting a name and an @ in front of a pattern. For instance, the pattern xs@(x:y:ys). This pattern will match exactly the same thing as x:y:ys but you can easily get the whole list via xs instead of repeating yourself by typing out x:y:ys in the function body again. Here's a quick and dirty example:

  1. capital :: String -> String  
  2. capital "" = "Empty string, whoops!"  
  3. capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]  
  1. ghci> capital "Dracula"  
  2. "The first letter of Dracula is D"  


본 카테고리의 내용은 Learn You a Haskell for Great Good! 의 내용을 학습을 위해 요약한 것입니다.