Fun with Haskell

My interest in Haskell arose while studying functional programming in Lisp. While Lisp is not used as widely today, languages like Haskell, Scala & Clojure are fairly prominent. Haskell seemed to be the most unique & interesting to me as it is a pure & lazy FP language. I also really enjoyed some quirky yet intriguing videos by Simon Peyton Jones on Haskell & its history. He often talks about 3 of his mottos that he developed while working on Haskell: - Purity is embarassing - Laziness is cool - Success should be avoided at all costs

So I wanted to give Haskell a try & started reading this funky book called “Learn You a Haskell” which is freely available online. I’m roughly halfway into the book & wanted to talk about some cool Haskell features I’ve learned so far.

Haskell reads like math

Haskell’s list comprehensions tend to remind me a lot of my high school math books. For eg., to take a list of numbers from 1 to 10 & multiply them by 2, you simply write :

[x*2 | x <- [1..10]]

The ease with which you can express mathematical problems in Haskell so succintly just blows me away sometimes! Here’s a one liner to find the no of right triangles where each side has an integer length less than or equal to 10 :

rightTriangles = [(a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10], a^2 + b^2 == c^2]

Here’s another one line function to calculate the length of a list :

length xs = sum [1 | _ <- xs]

The _ symbol means we don’t care about the value of the specific list element

Haskell has type inference

While a function like factorial n = product [1..n] will work perfectly fine in Haskell, we can add a type signature to our function definition as well which makes the function more readable :

factorial :: Integer -> Integer  
factorial n = product [1..n]

Recursion feels so natural

Haskell is built for recursion. Here’s a simple function to reverse a list, using the ++ list append operator. [] refers to the empty list which is the base case when doing recursion on lists :

reverse [] = []  
reverse (x:xs) = reverse' xs ++ [x]

Let’s take a loot at the popular quicksort algorithm to sort lists in Haskell :

quicksort [] = []  
quicksort (x:xs) =   
    smallerSorted ++ [x] ++ biggerSorted
    where   smallerSorted = quicksort [a | a <- xs, a <= x]  
            biggerSorted = quicksort [a | a <- xs, a > x]

Pattern Matching rocks

We can rewrite the factorial function above in a recursive style as well, starting with the base case first, and then writing the inductive case :

factorial 0 = 1  
factorial n = n * factorial (n - 1)

This feels more natural, and more math-y! The length function from above can also be re-written like this :

length :: [a] -> Int
length [] = 0  
length (_:xs) = 1 + length xs 

Here, a (sometimes pronounced as alpha by ML hackers) is a type variable that can have any type. It makes the function length more powerful as it can take a list of any data type as input, but the function will always return a value of type Int.

Build using Higher order functions

Haskell comes with built-in support for a lot of high level functions like map, filter, fold (foldl, foldr), zip, etc.

To find the largest number under 100,000 that’s divisible by 3829, we can make use of Haskell’s laziness as :

largestDivisible = head (filter p [100000,99999..])  
    where p x = x `mod` 3829 == 0

Although we pass an infinite list, due to Haskell’s laziness, evalutation will stop once we find the head ie first element of the list that satisfies the filter.

Here’s another example using map, to find the sum of all odd squares that are smaller than 10,000 :

sumOddSq = sum (takeWhile (<10000) (map (^2) [1, 3..]) )

This was a quick summary of some interesting programming ideas that I’ve seen in Haskell so far. Although I know I’ve barely scratched the surface here, I’m yet to study more advanced concepts like monads, typeclasses, monoids & dealing with laziness. I’ll try & share my learnings of these topics as I go along.


PS - If you’re interested in functional programming, I’ll highly recommend the Programming Languages MOOC by Prof Dan Grossman. While the course uses Standard ML to teach statically typed functional programming (Part A), most concepts were taught in such a generalized manner that I could easily apply them to Haskell as well !!

PPS - Special thanks to the Reddit User u/Noughmare for helping me fix bigs in this article!

2020

Fun with Haskell

3 minute read

My notes halfway through the book Learn You A Haskell

Back to Top ↑