I’m currently reading (and thoroughly enjoying!) a fantastic book called Learn you a Haskell for great good. The author is Miran Lipovača, and I gotta say that he’s one of the most entertaining writers I’ve ever come across. If you like programming, then get this book. It’s worth every cent. Oh, and because Miran is such a nice guy, you can read the book for free on the website. Awesome. But please don’t let that deter you from actually buying it. We want him to write more books like this, and people gotta eat you know.
I started reading this book because I wanted to dip my toes in the hot waters of functional programming, and Haskell appealed to me, primarily because I’ve wanted to start using the xmonad tiling window manager on my Slackware box. I came at Haskell with a very imperative mindset, knowing little to nothing about functional programming. I had some vague ideas about what I was getting into, but for the most part I believed it to be a matter of learning a new syntax.
Boy was I wrong.
Obviously you have to learn a new syntax, but you also have to learn to think in a completely new way. And to be honest, I’m finding it pretty darn hard, in a very pleasurable way. Haskell is nothing like anything else I’ve ever encountered. Let me give you an example. Early in the book the concept of list comprehensions are introduced, and alongside these a cute little task:
Which right triangle that has integers for all sides and all sides equal to or smaller than 10 has a perimeter of 24?
While this task is by no means rocket science, it does require a bit of effort to solve in a typical imperative language, and you’d probably end up with some less than pretty nested loops, perhaps something like this:
with Ada.Text_IO; procedure Triangle is use Ada.Text_IO; Max_Length : constant Positive := 10; Perimeter : constant Positive := 24; begin for A in 1 .. Max_Length loop for B in A + 1 .. Max_Length loop for C in B + 1 .. Max_Length loop if (A*A) + (B*B) = C*C and then A+B+C = 24 then Put (A'Img & B'Img & C'Img); end if; end loop; end loop; end loop; end Triangle;
Yea I know – not pretty, but there it is and the result when running this little marvel is
6 8 10
Now lets see the Haskell way:
[(a,b,c) | c<-[1..10], b<-[1..c], a<-[1..b], a^2+b^2==c^2, a+b+c==24]
Simply enter the above in
ghci (Haskell interactive mode), and you’ll get
Solved using one line. How awesome is that? And it’s very readable to boot! The three lists feed into the
(a,b,c) triple according to the two predicates
a+b+c==24. And that’s it! Lets try and remove the last predicate
[(a,b,c) | c<-[1..10], b<-[1..c], a<-[1..b], a^2+b^2==c^2]
and see what we get:
Those two triangles are the only Pythagorean triples within the range of 1..10. Very neat.
If you’re up for some fun, I can highly recommend taking a look at Haskell. It’s a language that appears to be jam-packed with all sorts of great/cool features and as if that wasn’t enough, you also get to use words like monads, zippers, monoids and functors. Get your Haskell groove on here.