Haskell allows pattern matching. The following function counts one, two or many objects
```lisp
simpleCount 1 = "One"
simpleCount 2 = "Two"
simpleCount _ = "Many"
```
You can use pattern matching to set base cases in recursive functions.
```lisp
factorial 0 = 1
factorial n = n * factorial (n-1)
```
Haskell also allows guards. This if statement checks if someone is old enough to drive in the UK
```lisp
canDrive x = if x<18 then "Too young to drive" else "Old enough to drive"
```
Here it is using guards:
```lisp
canDrive x
| x<18 = "Too young to drive" |
| otherwise = "Old enough to drive" |
```
## pcase
Emacs Lisp offers similar functionality with the pcase macro. It took me some time to understand the documentation, so here are few examples to get you going. They only scratch the surface, make sure you go back and [read up properly](https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html#pcase%2dsymbol%2dcaveats) afterwards.
```lisp
(defun simple-count (x)
(pcase x
(1 "one")
(2 "two")
(_ "many")))
(mapcar #'simple-count '(1 2 5))
=> ("one" "two" "many")
```
Note that \_ is used for the don't care or wildcard case, rather than the more traditional t.
```lisp
(defun can-drive (x)
(pcase x
((guard (< x 18)) "Too young to drive")
(_ "Old enough to drive")))
(can-drive 12)
=> "Too young to drive"
```
The following converts a test mark into a grade. Note the use of **and** to evaluate **(pred stringp)**. If non nil, it binds **x** to **msg**. In other words, pcase can distinguish between marks and teacher comments.
```lisp
(defun student-grade (x)
(pcase x
((and (pred stringp) msg) msg)
((guard (< x 10)) "Fail")
((guard (< x 20)) "C")
((guard (< x 30)) "B")
(_ "A")))
(mapcar #'student-grade '("Absent" 23 12 "off roll" 9 35))
=> ("Absent" "B" "C" "off roll" "Fail" "A")
```
Take a look at this example from the documentation. Again, it uses **and** to evaluate **(pred stringp)**. If non nil, it binds x to msg.
So, if x is a string, print it; if x is a recognised symbol, print the associated message; otherwise print unknown return code.
```lisp
(defun my-errors (x)
(pcase x
;; string
((and (pred stringp) msg)
(message "%s" msg))
;; symbol
('success (message "Done!"))
('would-block (message "Sorry, can't do it now"))
('read-only (message "The shmliblick is read-only"))
('access-denied (message "You do not have the needed rights"))
;; default
(code (message "Unknown return code %S" code))))
(mapcar #'my-errors '(1 read-only "hello"))
=> ("Unknown return code 1" "The shmliblick is read-only" "hello")
```