I spent three days up in Brisbane between March 17-19 on a course called “Introduction to Functional Programming using Haskell“. It was intense!
The course was run by Tony Morris & Mark Hibberd from NICTA, and Katie Miller from Red Hat. It was originally billed as Lambda Ladies, but it turns out there weren’t quite enough ladies to fill the course, so anyone else interested was invited along too.
The course is a bunch of practical exercises. They excluded the standard Haskell library from the project, and we spent time reimplementing first principles, starting with functions involving Lists. It’s a very hands-on way of learning how Haskell works. The first day covers pattern matching, folding and functional composition, the next couple deals with abstracts on binding & functors, getting towards monads. You spend some time implementing a couple of concrete problems – a string parser, and a problem involving file IO – to see Haskell in practice.
If you’re familiar with functional programming, you’d understand that’s a LOT of material to cover in three days. I would say that the average learning curve went a bit like this:
However, having a solid understanding of programming concepts (e.g. lambdas) meant that the more complex concepts were a lot easier to pick up (to a degree). When I was learning functional programming at university, it took me days to reimplement map properly in Haskell! Earlier this week, it took five minutes.
Getting to your solution for each problem felt a lot like algebraic substitution and refactoring. First, you make it work, and then you refactor constantly to get the most elegant (read: shortest) solution by taking advantage of functional composition.
I was surprised at how much it ended up looking like a normal chained method once you introduce the point notation, aka functional composition, which is something C# looks to have borrowed heavily from when introducing LINQ.
To take the example from the link above,
ghci> map (\xs -> negate (sum (tail xs))) [[1..5],[3..6],[1..7]] [-14,-15,-27]
turns into…
ghci> map (negate . sum . tail) [[1..5],[3..6],[1..7]] [-14,-15,-27]
I was also surprised just how much of a rush it was to a) have a solution that type checked properly, and b) actually worked. Haskell felt like an all-or-nothing proposition, where it either compiled and worked, or was otherwise hopelessly broken and gave you a type checked error that was difficult to decipher. Otherwise, most other programming languages have a more granular feedback loop and are much easier to debug – you can put logging statements in, for example.
The best takeaway of all were these amazing lambda earrings!
Learn You a Haskell is an excellent (and cute, and free) resource for learning Haskell.