Monday, January 27, 2014

Book Review: Learn You a Haskell for Great Good!

I recently finished reading Learn You a Haskell for Great Good! by Miran Lipovača (Amazon Link). And, yes, it did take me a long time to get through this book -- mainly due to other distractions. I started reading this way back in October, got a good start, and then let it sit around for a while.

I'll split this into 2 parts -- the basics and the more advanced stuff.

The Basics
Learn You a Haskell gives a fairly gentle introduction to functional programming and the Haskell language. Lipovača understands that functional programming is an unfamiliar concept to many programmers who are starting out with Haskell. As such, he combines functional programming concepts with the description of how the various elements of the language work.

Haskell is a purely functional language, meaning that functions are first-class citizens (actually, the only citizens). And it is built around the concepts of immutability, "no side effects", and repeatability. Some other functional languages have compromises that let them fit in with more imperative programming.

I found this very helpful as a first step into functional programming. I really had to start thinking about immutability and repeatability in my own Haskell code. There is no other way of doing it.

The book takes small steps in introducing new concepts. This is very additive in nature (which is nice). And to describe some of the basics, the examples build simple functions based on prior learnings. Often, these simple functions end up as standard functions that are supplied with the standard modules. But it's nice to see how these functions actually work.

For an example, take a look at the zipWith' function (which I mentioned earlier in a different context):


This is from Chapter 5 (Higher-Order Functions) and shows several different concepts that are covered earlier. The concepts include function declaration (the first line), lists (the angle brackets), filters (the last 3 lines that work like a "case" statement), working with head/tail on lists (the "x:xs" and "y:ys"), and recursion (the "zipWith'" call in the last line).

This particular example is to add on the "higher-order function" part. A higher-order function is a function that takes another function as a parameter. In this case, the zipWith' function takes a function and 2 lists as parameters. Then it applies the function to each element of the lists and returns a list.

For example:
zipWith' (+) [1,2,3] [4,5,6]
Takes the "+" function (yes, that's really a function in Haskell) and uses it with the first element of each list, then the second element of each list, and so on. So, it calls "1 + 4", "2 + 5", and "3 + 6".  The result is a list: [5, 7, 9].

And of course, this leads to the Foo Bar example that I actually like.

The Advanced Stuff
The skill level ramps up. Lots of concepts are covered including Functors, Applicative Functors, Monoids, and Monads.

Things were a little fuzzy to me in the middle of the book. Since Lipovača uses the "building on previous knowledge" approach. I figured that I would be totally lost for the rest of the book, but I kept pressing forward.

What I found was that I was able to pick things back up again. For example, I got a bit lost in the description of applicative functors. But then, moving on to monoids, Lipovača describes how monoids build on top of applicative functors. And for some reason, reviewing the old material in conjunction with the new material made the old concept "click" with me.

Where I Explored Further
To help me get acquainted with Haskell (and functional programming in general), I took a look at the Euler problems. These are math-related problems that really lend themselves to being solved functionally. I used these to get me to start thinking functionally. I wrote about my encounter with the first Euler problem a few months back.

And I spent quite a bit of time on the second Euler problem. This deals with the Fibonacci sequence. I have a bit of fondness for the Fibonacci sequence. I have used a non-recursive implementation in C# in some of my previous examples. Since the Fibonacci sequence is often solved with a recursive function, I started there.

What I found is that creating a Fibonacci sequence with a classic recursion method is extremely slow. So, I spent some more time trying different approaches. And I found some really interesting Haskell examples online with completely different approaches. I'll talk about these in a later article.

Wrap Up
I found Learn You a Haskell for Great Good! to be a really good resource for me. It gave me a good overview of functional programming concepts. Now, I have had some exposure to functional concepts; I've been exploring them casually for the last year or so. Someone who is brand new to functional programming may need to spend a bit more effort on the early chapters. But that effort will pay off.

So, I put Learn You a Haskell for Great Good! into the "recommended" category. Check it out if you want to get started with programming in a purely functional language.

Happy Coding!

No comments:

Post a Comment