For years, I’ve wanted to learn more about functional programming. It’s a very different method of providing solutions to problems (which, after all, is all programming is about, in the most generic sense possible). Now that things have calmed down a bit in the rest of my life, I’m making a concerted effort to understand it. After talking with Franklin Chen, he recommend Learn You a Haskell for Great Good.

I just started today – it was very simple to download the Haskell platform and get it up and running on my Mac Air (although if you don’t already have Xcode installed, it may be a little more difficult and/or time-consuming). Run the installer, open a terminal, type ghci, and you should be good to go.

I spent a few easy hours this morning setting up and going over the first part. List semantics were relatively straightforward (e.g., head and tail instead of the car and cdr I vaguely remember from my one undergrad class in Lisp). My first a-ha moment (the whole reason I’m doing this exercise in learning Haskell is to maximize the number of a-ha moments) was the section on list comprehensions. If you’re familiar with set theory, this is just like set comprehensions: describe what a set should contain, and the set just kind of has it. In Haskell, replace sets with lists, but for simple purposes, you can ignore that. For example, let’s say you wanted the set of all positive integers less than 10. In the GHCI (the Haskell REPL), just type:

[x | x <- [1..9]]

and you get…

*Main> [x | x <- [1..9]]

[1,2,3,4,5,6,7,8,9]

But let’s say you wanted only the ODD numbers less than 10. Just add a filter (in math-speak, a predicate):

[x | x <- [1..9], odd x]

…and you get:

*Main> [x | x <- [1..9], odd x]

[1,3,5,7,9]

Cool! You can arbitrarily add predicates easily, as well.

*Main> [x | x <- [1..9], odd x, x > 5]

[7,9]

Super-cool!

You can do this in Ruby, as well, but it seems much more a fundamental part of Haskell. That’s why people say that learning a functional language can help you in the other languages you program in. I’m looking forward to more a-ha moments as I go on.

Also, the number one improvement idea I got from my Sentiment Analysis talk was “quit using Komodo Edit”, so I’m forcing myself to do everything with Aquamacs now.

Congrats on getting set up and going!

I have an important observation to make: list comprehensions are actually NOT a “fundamental” part of Haskell. They are syntactic sugar on top of what is called “Core Haskell”. Eventually you’ll want to understand the nature of Core Haskell and how FPLs are implemented, but I think an important feature of FPLs is how they are typically layered on top of a very small core. Also, the power of comprehensions in general goes well beyond lists; eventually, you’ll learn about monad comprehensions and other such things.

Interesting. I didn’t realize that they weren’t central to Haskell, but hopefully that will be one more “a-ha” moment that I have going forward. Does LYAH go into what elements comprise Core Haskell and which are just syntactic sugar? There’s occasional mentions of “this is just syntactic sugar” but so far I haven’t seen a list of what’s core and what’s extra.

I’ll worry about monads when I get to them – someone tried to explain them to me and I don’t think I quite understood. Hopefully, grokking simpler comprehensions will help me with them.

I like how “Hello, World!” is Chapter 9 of Learn You a Haskell instead of Chapter 1 – there’s quite a bit to know. Thanks for the clarification!

This discussion has inspired me to decide to write a detailed blog post about comprehensions, syntax, etc… on my to-do list for the coming week!

Monads are something not to get into yet for a while; it’s wise to wait. There are a bazillion articles about them out there, and I haven’t been entirely happy about any of them, so that’s something else I’ll have to write about too!

There’s one that I generally recommend: http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html

…And when you will discover that list comprehension is just syntactic sugar, your mind will blow

I am on the same journey… I’ve finished reading LYAHFGG, but I am re-re-re-re-re-reading over and over Chapters 11, 12, 13 to better grab these concepts.

This reading is slowly changing my way of reasoning, even when I code in other languages… It’s a very enlightening experience.

For practicing I started to solve Project Euler’s problems.

Project Euler has been a great way for me to learn Haskell. I had done many of the problems earlier in Python, and it’s amazing to see how much shorter and more elegant the Haskell versions are.

List comprehensions are just syntactic sugar for the list monad, which is in turn just syntactic sugar for `concatMap`. Your last example gets translated to:

do

x 5)

That in turn just translates to:

[1..9] >>= \x ->

guard (odd x) >>= \() ->

guard (x> 5)

When you specialize `(>>=)` to lists, you get:

m >>= f = concatMap f m

… and when you specialize `guard` to lists, you get:

guard p = if p then [()] else []

However, there is an even simpler way to implement your function, which is not to use list comprehensions or the list monad at all. You can just write:

filter (\x -> odd x && x > 5) [1..9]

Because Haskell is pure and referentially transparent, you can prove that the two alternatives are exactly equal, no matter what the argument list is.

In GHC, list comprehensions are actually compiled to foldr/build fusion, not concatMaps. This means that list comprehensions sometimes are more efficient than using do-notation.

Just to be “that guy”:

Prelude> [1,3..9]

[1,3,5,7,9]

I love Haskell too.

Ha ha, very true. Just like perl, there’s more than one way to do it. =) I was just trying to show off list comprehensions using the same syntax, of course.