Personal tools

How to read Haskell

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
m
Line 18: Line 18:
 
When reading a long piece of Haskell code, one which is broken up into many modules, you should consider keeping a browser window open with the auto-generated API documentation on the side (if any).
 
When reading a long piece of Haskell code, one which is broken up into many modules, you should consider keeping a browser window open with the auto-generated API documentation on the side (if any).
   
=== Hint: a function may be defined in more than one piece ===
+
== What does this function do? ==
  +
  +
=== Trick: use type signatures ===
  +
  +
When you see stuff like this
  +
<haskell>
  +
-- example please!
  +
foo :: Bar Ping Pong -> Baz Zed Dubya -> IO (DoublePlus Good)
  +
</haskell>
  +
...don't fight it! These are type signatures and they are an incredibly useful way of getting a rough idea what a function is supposed to do.
  +
  +
:''elaborate''
  +
  +
=== Tip: a function may be defined in more than one piece ===
   
 
Remember math class, where functions would be defined like abs(x) = x if x >= 0 or -x otherwise? It's a bit like that in Haskell too. Sometimes, rather than writing one big if-then-else, Haskellers find it more convenient to define a function separately for each case, such as...
 
Remember math class, where functions would be defined like abs(x) = x if x >= 0 or -x otherwise? It's a bit like that in Haskell too. Sometimes, rather than writing one big if-then-else, Haskellers find it more convenient to define a function separately for each case, such as...
Line 43: Line 43:
 
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.
 
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.
   
==== Hint: order doesn't matter ====
+
==== Tip: order doesn't matter ====
   
 
Outside of a monad, it really doesn't matter what order things in Haskell code appear. So if you see something like this...
 
Outside of a monad, it really doesn't matter what order things in Haskell code appear. So if you see something like this...
Line 54: Line 54:
 
:* ''except for monads? explain''
 
:* ''except for monads? explain''
   
==== Hint: use grep ====
+
==== Trick: use grep ====
   
 
(This might seem really obvious, but it's sometimes easy to forget)
 
(This might seem really obvious, but it's sometimes easy to forget)
Line 77: Line 77:
   
 
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]
 
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]
 
=== Hint: use type signatures ===
 
 
When you see stuff like this
 
<haskell>
 
-- example please!
 
foo :: Bar Ping Pong -> Baz Zed Dubya -> IO (DoublePlus Good)
 
</haskell>
 
...don't fight it! These are type signatures and they are an incredibly useful way of getting a rough idea what a function is supposed to do.
 
 
:''elaborate''
 
   
 
----
 
----

Revision as of 16:26, 13 August 2006

This stub is intended to become a tutorial on reading Haskell. It's aimed at the non-Haskeller who probably doesn't care too much about trying to write code, but wants to understand it.

Contents

1 The tutorial

...needs to be written (actually, Haskell for C Programmers seems to do this job)

-- insert here some horrible (for the non-Haskeller) long example
-- something we can work through slowly (and show why we find it beautiful)

2 Practical tips

2.1 Hint: use the haddock

When reading a long piece of Haskell code, one which is broken up into many modules, you should consider keeping a browser window open with the auto-generated API documentation on the side (if any).

3 What does this function do?

3.1 Trick: use type signatures

When you see stuff like this

-- example please!
foo :: Bar Ping Pong -> Baz Zed Dubya -> IO (DoublePlus Good)

...don't fight it! These are type signatures and they are an incredibly useful way of getting a rough idea what a function is supposed to do.

elaborate

3.2 Tip: a function may be defined in more than one piece

Remember math class, where functions would be defined like abs(x) = x if x >= 0 or -x otherwise? It's a bit like that in Haskell too. Sometimes, rather than writing one big if-then-else, Haskellers find it more convenient to define a function separately for each case, such as...

abs x | x >= 0 = x
abs x = -x

What gets confusing is when you look at a definition like this...

foo x | blah = 
 some enormous long thing
 
foo x =
 some other enourmously long thing

Especially looking at the bottom bit, it's hard to remember that foo might have a another definition lurking around. Luckily, you never have to look very far, either immediately above or immediately below the other definition.

(Note: some programmers will perhaps write something like foo x | otherwise = .... The otherwise is redundant (and equal to True), but useful as reminder that this isn't the entire definition of foo)

3.3 What the heck is xyz?

One problem you might face when reading Haskell code is figuring out some cryptic entity like xyz is.

3.3.1 Tip: order doesn't matter

Outside of a monad, it really doesn't matter what order things in Haskell code appear. So if you see something like this...

foo = whatTheHeckIsBar

you should take into account that whatTheHeckIsBar may be defined somewhere below foo

  • scope in a nutshell
  • except for monads? explain

3.3.2 Trick: use grep

(This might seem really obvious, but it's sometimes easy to forget)

Or use the search feature of your favourite text editor. It's probably defined right there before your eyes, and if it's true to Haskell style, the definition is probably so small you blew right through it. In vi, for example, you could do /= *xyz which searches for =, an arbirtary number of spaces, and then xyz.

Barring that, xyz might be defined in some different module in the code you downloaded. You can look for telltale signs like

import Manamana (xyz)

But note that sometimes programmers get lazy, and they don't specify that xyz should be imported. They just let rip with

import Manamana

So solution number 3 would be do something like grep xyz *.lhs *.hs (Note that literate programs sometimes use non-literate code, so search in both lhs AND hs)

A fourth idea, if you can't find something, is to look it up in Hoogle


4 What confuses non-Haskellers

Since this tutorial is not yet written, we encourage you to note here the things which confuse non-Haskellers about the code code.

  • layout instead of semicolons?
  • super-super-concise stuff (things using liftM and liftM2)
  • the difference between
    x <- foo
    and
    x = foo