A glance at some Haskell books

Today is a good day! I finally got my hands on two Haskell books: Programming in Haskell by Graham Hutton and Real World Haskell from O’Reilly. We’ll take a quick look at them, but first let me mention Learn You A Haskell for Great Good (commonly known as LYAH). If you’re wondering what is the best way to start learning Haskell then LYAH is probably it. It’s available online, but you can buy it as a book as well. It is written in a very accessible way – I’ve read most of it and so far there has been not a single thing that was unclear in any way. The only downside of LYAH is the lack of any kind of exercises. This forces you to be creative and come up with your own problems or perhaps try solving problems available on the web. Two common choices are the 99 Haskell Problems, which have a steep difficulty curve IMO, and Project Euler, which some people don’t recommend claiming that one should concentrate on the language itself, not on the difficult algorithms. Anyway, let’s look at the books.

Programming in Haskell covers rather basic material. It seems that some stuff that is in LYAH is not here. It’s hard for me to judge how many new material the book offers (comparing to LYAH), but I have an impression that it explains stuff from a formal point of view, whereas LYAH is more pragmatic and doesn’t go into theory of the language. There are exercises and I think that’s very important. I’ve also noticed some very nice example, namely the Game of Life. The book isn’t very long. It has only 170 pages. Despite its large format, there’s not to much text since the margins are about one third of the page width.

Real World Haskell is a different kind of book. In Poland such a thick book goes by the name of a brick. It’s almost 700 pages long and seems to cover lots of advanced material. I don’t think it’s a kind of book that’s suitable for newbies. It doesn’t seem to teach things in a quick and concise way, rather going into many details. This looks like the book that every person that wants to be a serious Haskell programmer has to read – I don’t think there is any competition to it a the moment. There’s a lot of practical stuff: interfacing with C, connecting to databases, using JSON, recognizing barcodes, testing, parsing, making a GUI, concurrent programming, profiling, software transactional memory and more. I like the fact there are many case studies. You can check it out yourself, since this book is also available online for free.

Now I have to find free time to read both of them.

Compiling GHC. Just for fun

A few days ago I wrote about installing GHC on openSUSE Linux. I stated that “[compiling GHC from source] is not really a sane option“. I did that based on opinion heard from others. In the next post about recursion I complained that “most of us programmers (…) follow assume-don?t-verify policy“. Oops, I fell into my own trap! It’s time to fix that. Today I decided to compile GHC from source. Just for fun.

OK, in fact I didn’t plan to do it. It just happened :) I went to github.com to see what projects are developed using Haskell. Finding a GHC repository wasn’t a big surprise. I cloned the repo just to check the size of the source. It was 17 MB – not much, really. That was intriguing, but the description of the repo at github provides a link to another GHC source repository. I cloned that one and got 85 megs of source (including repo data). That’s definitely more then in the previous case. The next step is running the script that fetches data from additional repositories (libraries, I guess). This increased the source size to around 250MB. Having the source I simply could not resist to build it.

First step was running some perl script and then it is a standard configure – make – make install procedure. First attempt on the building process failed. It turned out that I was missing header files for ncurses, but configure script missed that fact. After installing ncurses-devel the build was successful. GHC building instructions say:

You need to configure your build: which things to build, how much optimisation to use, whether to build profiling libraries, and so on. If you don’t do this, then you get everything, and it will be optimised to the hilt, which means the build will take a Very Long Time. This is fine if you wanted to build GHC for installation and use, but not if you’re building GHC to do some development work on it.

I didn’t customize my build and it took 1,5 hour on an iCore7 processor (2,66GHz). Too bad the build uses only one core, but it reminded of the times when I was compiling Linux kernel or MPlayer on a 333MHz Celeron – these were sometimes even longer. After the build finished the source directory grew to 2,5GB. I didn’t build the documentation and I skipped the make install part since I wanted only to play around with the building process, not messing up my system’s setup.

Now a few more notes. GHC uses a technique called bootstraping. It means that the compiler itself is written in Haskell and it needs a Haskell compiler to compile (I think that’s the main reason why compiling from source is not suitable for newbies). The build itself is divided into stages. Stage 0 is the compiler present in the system. Stage 1 is the first build of the new compiler that is later used during stage 2 to compile packages and build the compiler once more. Documentation explains the reason for rebuilding the compiler in the second stage in a way that is not yet fully clear to me:

Stage 1 does not support interactive execution (GHCi) and Template Haskell. The reason being that when running byte code we must dynamically link the packages, and only in stage 2 and later can we guarantee that the packages we dynamically link are compatible with those that GHC was built against (because they are the very same packages).

Generally compilation turned out to be relatively easy, although I think that people not developing the compiler (and newbies especially) should just rely on the binaries provided on the GHC site.

Function composition and $ operator in Haskell

Today I was trying to understand how function application, composition and $ work in Haskell. Consider two following lines of code:

take 3 (reverse (filter even [1..10]))
take 3 . reverse . filter even $ [1..10]

These are equivalent and both produce a list [10,8,6]. First version is based on grouping function calls with parentheses and this is pretty straightforward. My problem was the second version which is based on function composition and a special function application operator, denoted as . (dot) and $ respectively. This form is often used to write functions in a pointfree style1. I was trying to work out in what order function calls are executed and why do I have to use $ operator. Here’s what I came up with.

The function composition (dot) operator is defined as:

(.) :: (b -> c) -> (a -> b) -> a -> c
(f . g) x = f (g x)

This operator has priority of 9 and is right-associative2. This means that a . b . c . d is the same as (a . (b . (c . d))). The $ operator is defined as:

($) :: (a -> b) -> a -> b
f $ x = f x

This operator simply applies a function to a given parameter. In contrast to standard function application, which has highest possible priority of 10 and is left-associative, the $ operator has priority of 0 and is right-associative (that second property doesn’t matter in my example). Such a low priority means that all other operators on both sides of $ will be evaluated before applying the $. So the call

take 3 . reverse . filter even $ [1..10]

will first evaluate take 3 . reverse . filter even constructing a partially applied function that becomes fully applied when it receives one more parameter. The missing parameter is the list on the right side of $. By definition of dot operator, this call is therefore equivalent to take 3 (reverse (filter even [1..10])). That’s what we expected.

Why do we need the $ operator? If it wasn’t there then the function call filter even [1..10] would evaluate first – remember that function application has priority of 10, while function composition has a lower priority of 9. This would lead to take 3 . reverse . [2,4,6,8,10], but a list cannot be composed with a function. The dot operator expects it’s second argument to be a function of one argument, not a list, and that’s the reason we need $ – to allow function composition to evaluate first.

  1. The name “pointfree” doesn’t come from the point operator used to compose functions []
  2. You can verify this by typing :i (.) in ghci. This will display the type definition, fixity (infixr in that case) and priority of the dot operator []

Staypressed theme by Themocracy