Haskell-like patterns in Lisp
27th January 2021
One of the nice features in Haskell is patterns, which provide an alternative to conditionals for expressing functions more elegantly.
For example, here's a recursive definition of factorial in Haskell using patterns:
fac :: Integer -> Integer fac 0 = 1 fac n = n * fac (n - 1)
It's perhaps a pity that Lisp doesn't provide patterns as an option. But wait a minute, if we consider CLOS part of Common Lisp we can use it to write many problems in a pattern-like way, without conditionals, just like in Haskell. Here's an example:
(defmethod fac ((n (eql 0))) 1) (defmethod fac (n) (* n (fac (1- n))))
Try it out:
> (fac 12) 479001600
Here's another example, from Learn Haskell Fast and Hard by Yann Esposito [1]:
Given a list of integers, return the sum of the even numbers in the list.
Here's a recursive definition in Haskell using patterns:
evenSum :: [Integer] -> Integer evenSum [] = 0 evenSum lis = (if even (head lis) then head lis else 0) + evenSum (tail lis)
Again, here's the pattern-like way of doing it in Lisp:
(defmethod evensum ((lis null)) 0) (defmethod evensum (lis) (+ (if (evenp (car lis)) (car lis) 0) (evensum (cdr lis))))
Try it out:
> (evensum '(0 1 2 3 4 5 6 7 8 9)) 20
- ^ Learn Haskell Fast and Hard on yannesposito.com.
blog comments powered by Disqus