|
| 1 | +# Introduction |
| 2 | + |
| 3 | +## Pattern Matching Literals |
| 4 | + |
| 5 | +While `if/else` expressions can be used to execute conditional logic, Haskell also has a more powerful way to execute conditional logic: [pattern matching][pattern-matching]. |
| 6 | +With pattern matching, a value can be tested against one or more _patterns_. |
| 7 | +An example of such a pattern is the _constant pattern_, which matches a value against a constant (e.g. `1` or `"hello"`). |
| 8 | + |
| 9 | +When defining functions, you can define separate function bodies for different patterns. |
| 10 | +This leads to clean code that is simple and readable. |
| 11 | +You can pattern match on any data type — numbers, characters, lists, tuples, etc. |
| 12 | + |
| 13 | +For example, a trivial function that takes a whole number (`Int`) and makes it _1_ closer to _0_ could be expressed like this: |
| 14 | + |
| 15 | +```haskell |
| 16 | +closerToZero :: Int -> Int |
| 17 | +closerToZero 0 = 0 |
| 18 | +closerToZero 1 = 0 |
| 19 | +``` |
| 20 | + |
| 21 | +Pattern matching starts to shine when used together with other patterns, for example the _variable pattern_: |
| 22 | + |
| 23 | +```haskell |
| 24 | +closerToZero :: Int -> Int |
| 25 | +closerToZero 0 = 0 |
| 26 | +closerToZero n = n - 1 |
| 27 | +``` |
| 28 | + |
| 29 | +The above example treats all inputs other than _0_ the same, and would produce incorrect results for negative numbers. |
| 30 | +This can be solved using conditional patterns, known as _guards_, which are expressed with the `|` symbol: |
| 31 | + |
| 32 | +```haskell |
| 33 | +closerToZero :: Int -> Int |
| 34 | +closerToZero n |
| 35 | + | n < 0 = n + 1 |
| 36 | + | n > 0 = n - 1 |
| 37 | +``` |
| 38 | + |
| 39 | +In the above examples not all possible inputs have a matching pattern. |
| 40 | +The compiler will detect this and output a warning. |
| 41 | +This is a very useful feature of Haskell that helps ensure all possible paths are covered to avoid run-time errors. |
| 42 | +It is known as _exhaustive checking_. |
| 43 | +To solve the warning, you have to handle all cases. |
| 44 | +Within _guards_ you can use the expression `otherwise` as syntactic sugar for `True` to catch all remaining patterns. |
| 45 | + |
| 46 | +```haskell |
| 47 | +closerToZero :: Int -> Int |
| 48 | +closerToZero n |
| 49 | + | n < 0 = n + 1 |
| 50 | + | n > 0 = n - 1 |
| 51 | + | otherwise = 0 |
| 52 | +``` |
| 53 | + |
| 54 | +Pattern matching will test a value against each pattern from top to bottom, until it finds a matching pattern and executes the logic associated with that pattern. |
| 55 | +**The order of patterns matters!** |
| 56 | + |
| 57 | +[pattern-matching]: https://learnyouahaskell.github.io/syntax-in-functions#pattern-matching |
0 commit comments