https://wiki.haskell.org/api.php?action=feedcontributions&user=Michael+T.+Richter&feedformat=atomHaskellWiki - User contributions [en]2024-03-19T11:19:33ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=How_to_read_Haskell&diff=13982How to read Haskell2007-07-04T03:15:11Z<p>Michael T. Richter: /* Tip: types, functions and values */</p>
<hr />
<div>This (very incomplete) tutorial is aimed at the non-Haskeller who probably doesn't care too much about trying to write code, but wants to understand it.<br />
Our adopted format is a collection of tips and tricks broken down by category. It probably isn't very important what order you read it in, but it might be good to start with the general advice. Please feel encouraged to make any complaints about Haskell on the discussion page! It will help us to improve this tutorial.<br />
<br />
Note: you should also consider having a look at [http://www.haskell.org/~pairwise/intro/intro.html Haskell for C Programmers]. It might be a good way to get over the culture shock.<br />
<br />
== General advice ==<br />
<br />
=== Tip: it's just very very concise ===<br />
<br />
One thing that can make Haskell hard to read is that Haskell code is extremely succinct. One tiny little piece of code can say a lot, so many times, when you are faced with something you don't understand, the best thing you can do is to think about it for some time. It will usually make sense after a while. The good news is that because of this succinctness, Haskell functions tend to be very small, which means that when you're trying to understand a difficult piece of Haskell, you normally do not have to look very far. It's just two sides of the same coin:<br />
* bad news: high density == spending more time per line of code<br />
* good news: succinctness == fewer lines of code to spend time on<br />
<br />
Spending on this time to get one tiny line of code may be frustrating, but it's well worth the effort, because the fact that a very small code is hard to understand probably means that it's very abstract, and the fact that it is abstract probably means that it's going to be used in many places. So understanding that one tiny line code, as painful as it may have been initially, can pay off in a big way.<br />
<br />
=== Trick: use the haddock ===<br />
<br />
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).<br />
<br />
== What does this function do? ==<br />
<br />
=== Trick: use type signatures ===<br />
<br />
When you see stuff like this<br />
<haskell><br />
map :: (a -> b) -> [a] -> [b]<br />
</haskell><br />
...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.<br />
<br />
For example, the function above takes any function that turns an 'a' into a 'b' ('a -> b') and yields a function that takes a list of a's ('[a]') and produces a list of b's ('[b]'). For example, 'sqrt' takes a number and returns the square root of that number, so 'map sqrt' takes a ''list'' of numbers and returns a ''list'' of their square roots.<br />
<br />
As another example,<br />
<haskell><br />
swap :: (a,b) -> (b,a)<br />
</haskell><br />
This takes a tuple ('(a,b)') and swaps its values around ('(b,a)').<br />
<br />
Hint: If you see '->' inside brackets, then you have a high-order function. (A function that takes another function as a parameter.) These are extremely common in Haskell.<br />
<br />
Hint: If the type has 'IO' in it anywhere, it does something to do with input/output. (Conversely, if there isn't any 'IO' in the type, the function cannot ''possibly'' perform any I/O of any kind.) Most usually the IO part comes at the end, either as 'IO ()' ("this function does some kind of input and/or output, and doesn't 'return' anything useful") or as something like 'IO Int' ("this function does input and/or output and returns an Int").<br />
<br />
:''Lots more hints could be added here. How much do we want to go into this? (Perhaps mention lists and tuples, since they have weird syntax?)''<br />
<br />
=== Tip: Haskellers love pattern matching ===<br />
<br />
<haskell><br />
head [x] = x<br />
</haskell><br />
This says that if 'head' is followed by a list containing only 1 item, label that item as 'x', and then return 'x'. Another example might be<br />
<haskell><br />
fst (x,y) = x<br />
<br />
snd (x,y) = y<br />
</haskell><br />
These functions fetch the '''f'''ir'''st''' and '''s'''eco'''nd''' items in a tuple, respectively. It should be fairly obvious how they work.<br />
<br />
:''elaborate''<br />
<br />
=== Tip: a function may be defined in more than one piece ===<br />
<br />
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...<br />
<haskell><br />
abs x | x >= 0 = x<br />
abs x = -x<br />
</haskell><br />
<br />
What gets confusing is when you look at a definition like this...<br />
<haskell><br />
foo x | blah = <br />
some enormous long thing<br />
<br />
foo x =<br />
some other enormously long thing<br />
</haskell><br />
<br />
Especially looking at the bottom bit, it's hard to remember that <code>foo</code> might have a <em>another</em> definition lurking around. Luckily, you never have to look very far, either immediately above or immediately below the other definition.<br />
<br />
(Note: some programmers will perhaps write something like <code>foo x | otherwise = ...</code>. The <code>otherwise</code> is redundant (and equal to <code>True</code>), but useful as reminder that this isn't the entire definition of <code>foo</code>)<br />
<br />
=== Tip: pattern matching and guards can be mixed and matched ===<br />
<br />
:''elaborate''<br />
<br />
<haskell><br />
combine ((f,a,b,r):(f',a',b',r'):ss)<br />
| f == f' = combine ((f,a.+a',b.+b',r+r'):ss)<br />
combine ((f,a,b,r):ss) = (f,a,b,r) : combine ss<br />
combine [] = []<br />
</haskell><br />
<br />
== What the heck is xyz? ==<br />
<br />
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.<br />
<br />
=== Tip: the smaller the name, the smaller the scope ===<br />
<br />
Do you hate the way Haskell code is littered with short, meaningless name like <code>x</code> and <code>xs</code>? When Haskell programmers use names like that, it's often for good reason.<br />
<br />
First, typically, the short, "meaningless" names are contained within a very small space. Consider this typical (and inefficient!) implementation of a prime number generator:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
<br />
The where block contains a function with strange variables like <code>x</code> and <code>xs</code> and <code>p</code>. In a more verbose language this could be difficult to read simply because it's difficult to actually find the definitions of small variables in long blocks of code. In C, for example, these would usually be defined at the top of a function which could have dozens (if not hundreds) of lines of code. Thus you might want to see <code>p</code> named as <code>known_prime</code> and <code>xs</code> named as <code>candidate_primes</code> or the like.<br />
<br />
In this code, however, there is no such need for it. <code>p</code> is (implicitly) defined in the same line of code that uses it. <code>xs</code>, too, is defined there, as is <code>x</code>. Further all three variables use a popular naming convention which appends 's' to the names of lists (or equivalents) and uses single letters for singular values. The only unusual part is the selection of the pattern <code>(p:xs)</code> in the arguments over the more common <code>(x:xs)</code>. Here the programmer is signalling (subtly) that this list head is somehow different from a normal list. Quick inspection demonstrates that <code>p</code> is guaranteed to be a prime number.<br />
<br />
The reason coding can be expressed this way in Haskell without undue confusion is because of its extreme conciseness. The habits you've had to learn to manage more verbose languages simply don't apply anymore. It takes some getting used to, but it becomes a joy one you reach that point.<br />
<br />
This, however, is not the main reason for such "meaningless" names. The real reason for such names is even deeper. The Haskell language allows for unparallelled levels of abstraction through functional composition and higher-order functions. Where in most imperative languages a "function" (or, more often, a procedure masquerading as a function) is a pretty low-level entity with very specific, tangible functionality, Haskell functions can be extremely abstract. Consider this canonical implementation of <code>foldl</code> from the Prelude:<br />
<haskell><br />
foldl :: (a -> b -> a) -> a -> [b] -> a<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
</haskell><br />
<br />
This function is a highly-abstract one. It is, in fact, an abstraction of iterating over a list and computing an aggregate result. What kind of list? Pretty much any kind. What kind of computation? Anything you'd care to name. What kind of result? Anything that matches the type of the priming value. What "meaningful" names can you apply to the variables here? Should it look something like this (elided and formed to fit a reasonable screen)?:<br />
<haskell><br />
foldl binary_operation priming_value (list_head:list_body) = <br />
foldl <br />
binary_operation <br />
(binary_operation priming_value list_head)<br />
list_body<br />
</haskell><br />
<br />
Knowing a few simple conventions of Haskell variable naming (functions progress, typically, as f, g, etc. for example) makes the first, terse version far more readable as an abstract definition than does the second, verbose version&mdash;once you get used to it.<br />
<br />
=== Tip: types, functions and values ===<br />
<br />
Type variables in Haskell are typically named starting at <code>a</code>, <code>b</code>, etc. They are sometimes (but not often) decorated with numbers like <code>a1</code> or <code>b3</code>.<br />
<br />
Functions used as higher-order arguments are typically named starting at <code>f</code>, <code>g</code>, etc. They will sometimes be decorated with numbers like type variables and will also be decorated with the <code>'</code> character like <code>g'</code>. You would read this latter example as "Jee-prime" and it is typically a function that is in some way related to <code>g</code> used as a helper or the like. Occasionally functions may be given names that are not on this continuum as an aide memoir, for example a function parameter used internally as a predicate may be given the name <code>p</code>.<br />
<br />
Arguments to functions, or variables used exclusively inside short functions, are often given names starting at <code>x</code>, <code>y</code>, etc., again occasionally decorated by numbers. Other single-letter variable names may be chosen if they can act as a mnemonic for their role such as using a variable named <code>p</code> for a value known to be prime.<br />
<br />
Note that these are guidelines and not rules. ''Any'' of them can and will be ignored, modified and/or abused in ''any'' given piece of Haskell code. (A quick look at the Standard Prelude as provided in the Haskell 98 Report should be convincing enough for this.)<br />
<br />
=== Tip: the -s and m- habits ===<br />
<br />
There is a variable name habit that sometimes comes with short names. Typically, if you have a thing you want to name <code>x</code>, you'll sometimes want to name lists of these <code>xs</code>. As in the plural of <code>x</code>. So if you see a name like <code>as</code> or <code>bs</code> or <code>foos</code>, it's often good to mentally read that as "aeyes" (the plural of a), "bees" (the plural of b), and "foohs" (the plural of foo). It might seem obvious to some, but it took me a while to stop asking myself in situations like this, "<code>as</code>? What the heck is aey-ess?"<br />
<br />
Similarly, another habit you might see is people who begin variable names with m-. This is probably less common, but if you see a lot of m-, it might be because of the Maybe type. Sometimes we have <code>foo</code> of type <code>Whatever</code>, and <code>mfoo</code> of type <code>Maybe Whatever</code>. Relax, this isn't [http://en.wikipedia.org/wiki/Hungarian_notation Hungarian notation]. It's not something that's used systematically, or rigidly in any way.<br />
<br />
Both of these conventions are just helpful when you have both variants floating around in the same place, that is, when you have both Whatever and [Whatever] (that would be list of whatever), <code>x</code> and <code>xs</code> is a good way to indicate that they are both the same thing, except one comes in a list. Likewise, when you have both Whatever and Maybe Whatever in the same function, <code>x</code> and <code>mx</code> are too.<br />
<br />
Finally, library functions are sometimes suffixed with "l", "r", "_", "M" or "'". What do<br />
these mean?<br />
<haskell><br />
mapM -- the 'map' function lifted into a monad. An 'M' suffix implies that the function is a<br />
-- monadic version of an equivalent pure function <br />
mapM_ -- the '_' suffix indicates that the result of this computation is discarded, and () is<br />
-- returned (by analogy with the _ pattern).<br />
foldl -- a fold that traverses its structure left to right<br />
foldr -- a fold that traverses its structure right to left<br />
foldl' -- a fold that is strict in its accumulator, "'" is used to indicate a strict variant of<br />
-- a function<br />
</haskell><br />
<br />
=== Tip: order doesn't matter ===<br />
<br />
It doesn't matter what order functions are defined in. This:<br />
<haskell><br />
foo x y z = ...<br />
<br />
bar a b = ... foo b ...<br />
</haskell><br />
is exactly equivilent to this:<br />
<haskell><br />
bar a b = ... foo b ...<br />
<br />
foo x y z = ...<br />
</haskell><br />
Functions further up can call functions that are defined lower down, and vice versa. Functions can be written in any order at all. It doesn't matter.<br />
<br />
Very important: The ''parts'' that make up a single function ''are'' in a particular order -- and that order is very important. The order in which separate functions are defined ''doesn't'' matter.<br />
<br />
:* ''scope in a nutshell''<br />
:* ''last paragraph is weak''<br />
<br />
=== Trick: use grep ===<br />
<br />
(This might seem really obvious, but it's sometimes easy to forget)<br />
<br />
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 <code>/= *xyz</code> which searches for =, an arbirtary number of spaces, and then xyz.<br />
<br />
Barring that, <code>xyz</code> might be defined in some different module in the code you downloaded. You can look for telltale signs like<br />
<haskell><br />
import Manamana (xyz)<br />
</haskell><br />
<br />
But note that sometimes programmers get lazy, and they don't specify that <code>xyz</code> should be imported. They just let rip with<br />
<haskell><br />
import Manamana<br />
</haskell><br />
<br />
So solution number 3 would be do something like<br />
<code><br />
grep xyz *.lhs *.hs<br />
</code><br />
(Note that literate programs sometimes use non-literate code, so search in both lhs AND hs)<br />
<br />
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]<br />
<br />
A fifth idea, for Hugs/WinHugs users, is to use the ":find" command, ":find xyz" will open up your text editor with the appropriate module, jumped to the correct place. GHCi users can use ":i xyz" to get the place "xyz" is defined. (It won't open an editor, though.)<br />
<br />
[[Category:Tutorials]]</div>Michael T. Richterhttps://wiki.haskell.org/index.php?title=How_to_read_Haskell&diff=13981How to read Haskell2007-07-04T03:14:25Z<p>Michael T. Richter: /* Tip: the -s and m- habits */ Adding a section detailing some common primary naming conventions.</p>
<hr />
<div>This (very incomplete) tutorial is aimed at the non-Haskeller who probably doesn't care too much about trying to write code, but wants to understand it.<br />
Our adopted format is a collection of tips and tricks broken down by category. It probably isn't very important what order you read it in, but it might be good to start with the general advice. Please feel encouraged to make any complaints about Haskell on the discussion page! It will help us to improve this tutorial.<br />
<br />
Note: you should also consider having a look at [http://www.haskell.org/~pairwise/intro/intro.html Haskell for C Programmers]. It might be a good way to get over the culture shock.<br />
<br />
== General advice ==<br />
<br />
=== Tip: it's just very very concise ===<br />
<br />
One thing that can make Haskell hard to read is that Haskell code is extremely succinct. One tiny little piece of code can say a lot, so many times, when you are faced with something you don't understand, the best thing you can do is to think about it for some time. It will usually make sense after a while. The good news is that because of this succinctness, Haskell functions tend to be very small, which means that when you're trying to understand a difficult piece of Haskell, you normally do not have to look very far. It's just two sides of the same coin:<br />
* bad news: high density == spending more time per line of code<br />
* good news: succinctness == fewer lines of code to spend time on<br />
<br />
Spending on this time to get one tiny line of code may be frustrating, but it's well worth the effort, because the fact that a very small code is hard to understand probably means that it's very abstract, and the fact that it is abstract probably means that it's going to be used in many places. So understanding that one tiny line code, as painful as it may have been initially, can pay off in a big way.<br />
<br />
=== Trick: use the haddock ===<br />
<br />
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).<br />
<br />
== What does this function do? ==<br />
<br />
=== Trick: use type signatures ===<br />
<br />
When you see stuff like this<br />
<haskell><br />
map :: (a -> b) -> [a] -> [b]<br />
</haskell><br />
...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.<br />
<br />
For example, the function above takes any function that turns an 'a' into a 'b' ('a -> b') and yields a function that takes a list of a's ('[a]') and produces a list of b's ('[b]'). For example, 'sqrt' takes a number and returns the square root of that number, so 'map sqrt' takes a ''list'' of numbers and returns a ''list'' of their square roots.<br />
<br />
As another example,<br />
<haskell><br />
swap :: (a,b) -> (b,a)<br />
</haskell><br />
This takes a tuple ('(a,b)') and swaps its values around ('(b,a)').<br />
<br />
Hint: If you see '->' inside brackets, then you have a high-order function. (A function that takes another function as a parameter.) These are extremely common in Haskell.<br />
<br />
Hint: If the type has 'IO' in it anywhere, it does something to do with input/output. (Conversely, if there isn't any 'IO' in the type, the function cannot ''possibly'' perform any I/O of any kind.) Most usually the IO part comes at the end, either as 'IO ()' ("this function does some kind of input and/or output, and doesn't 'return' anything useful") or as something like 'IO Int' ("this function does input and/or output and returns an Int").<br />
<br />
:''Lots more hints could be added here. How much do we want to go into this? (Perhaps mention lists and tuples, since they have weird syntax?)''<br />
<br />
=== Tip: Haskellers love pattern matching ===<br />
<br />
<haskell><br />
head [x] = x<br />
</haskell><br />
This says that if 'head' is followed by a list containing only 1 item, label that item as 'x', and then return 'x'. Another example might be<br />
<haskell><br />
fst (x,y) = x<br />
<br />
snd (x,y) = y<br />
</haskell><br />
These functions fetch the '''f'''ir'''st''' and '''s'''eco'''nd''' items in a tuple, respectively. It should be fairly obvious how they work.<br />
<br />
:''elaborate''<br />
<br />
=== Tip: a function may be defined in more than one piece ===<br />
<br />
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...<br />
<haskell><br />
abs x | x >= 0 = x<br />
abs x = -x<br />
</haskell><br />
<br />
What gets confusing is when you look at a definition like this...<br />
<haskell><br />
foo x | blah = <br />
some enormous long thing<br />
<br />
foo x =<br />
some other enormously long thing<br />
</haskell><br />
<br />
Especially looking at the bottom bit, it's hard to remember that <code>foo</code> might have a <em>another</em> definition lurking around. Luckily, you never have to look very far, either immediately above or immediately below the other definition.<br />
<br />
(Note: some programmers will perhaps write something like <code>foo x | otherwise = ...</code>. The <code>otherwise</code> is redundant (and equal to <code>True</code>), but useful as reminder that this isn't the entire definition of <code>foo</code>)<br />
<br />
=== Tip: pattern matching and guards can be mixed and matched ===<br />
<br />
:''elaborate''<br />
<br />
<haskell><br />
combine ((f,a,b,r):(f',a',b',r'):ss)<br />
| f == f' = combine ((f,a.+a',b.+b',r+r'):ss)<br />
combine ((f,a,b,r):ss) = (f,a,b,r) : combine ss<br />
combine [] = []<br />
</haskell><br />
<br />
== What the heck is xyz? ==<br />
<br />
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.<br />
<br />
=== Tip: the smaller the name, the smaller the scope ===<br />
<br />
Do you hate the way Haskell code is littered with short, meaningless name like <code>x</code> and <code>xs</code>? When Haskell programmers use names like that, it's often for good reason.<br />
<br />
First, typically, the short, "meaningless" names are contained within a very small space. Consider this typical (and inefficient!) implementation of a prime number generator:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
<br />
The where block contains a function with strange variables like <code>x</code> and <code>xs</code> and <code>p</code>. In a more verbose language this could be difficult to read simply because it's difficult to actually find the definitions of small variables in long blocks of code. In C, for example, these would usually be defined at the top of a function which could have dozens (if not hundreds) of lines of code. Thus you might want to see <code>p</code> named as <code>known_prime</code> and <code>xs</code> named as <code>candidate_primes</code> or the like.<br />
<br />
In this code, however, there is no such need for it. <code>p</code> is (implicitly) defined in the same line of code that uses it. <code>xs</code>, too, is defined there, as is <code>x</code>. Further all three variables use a popular naming convention which appends 's' to the names of lists (or equivalents) and uses single letters for singular values. The only unusual part is the selection of the pattern <code>(p:xs)</code> in the arguments over the more common <code>(x:xs)</code>. Here the programmer is signalling (subtly) that this list head is somehow different from a normal list. Quick inspection demonstrates that <code>p</code> is guaranteed to be a prime number.<br />
<br />
The reason coding can be expressed this way in Haskell without undue confusion is because of its extreme conciseness. The habits you've had to learn to manage more verbose languages simply don't apply anymore. It takes some getting used to, but it becomes a joy one you reach that point.<br />
<br />
This, however, is not the main reason for such "meaningless" names. The real reason for such names is even deeper. The Haskell language allows for unparallelled levels of abstraction through functional composition and higher-order functions. Where in most imperative languages a "function" (or, more often, a procedure masquerading as a function) is a pretty low-level entity with very specific, tangible functionality, Haskell functions can be extremely abstract. Consider this canonical implementation of <code>foldl</code> from the Prelude:<br />
<haskell><br />
foldl :: (a -> b -> a) -> a -> [b] -> a<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
</haskell><br />
<br />
This function is a highly-abstract one. It is, in fact, an abstraction of iterating over a list and computing an aggregate result. What kind of list? Pretty much any kind. What kind of computation? Anything you'd care to name. What kind of result? Anything that matches the type of the priming value. What "meaningful" names can you apply to the variables here? Should it look something like this (elided and formed to fit a reasonable screen)?:<br />
<haskell><br />
foldl binary_operation priming_value (list_head:list_body) = <br />
foldl <br />
binary_operation <br />
(binary_operation priming_value list_head)<br />
list_body<br />
</haskell><br />
<br />
Knowing a few simple conventions of Haskell variable naming (functions progress, typically, as f, g, etc. for example) makes the first, terse version far more readable as an abstract definition than does the second, verbose version&mdash;once you get used to it.<br />
<br />
=== Tip: types, functions and values ===<br />
<br />
Type variables in Haskell are typically named starting at <code>a</code>, <code>b</code>, etc. They are sometimes (but not often) decorated with numbers like <code>a1</code> or <code>b3<code>.<br />
<br />
Functions used as higher-order arguments are typically named starting at <code>f</code>, <code>g</code>, etc. They will sometimes be decorated with numbers like type variables and will also be decorated with the <code>'</code> character like <code>g'</code>. You would read this latter example as "Jee-prime" and it is typically a function that is in some way related to <code>g</code> used as a helper or the like. Occasionally functions may be given names that are not on this continuum as an aide memoir, for example a function parameter used internally as a predicate may be given the name <code>p</code>.<br />
<br />
Arguments to functions, or variables used exclusively inside short functions, are often given names starting at <code>x</code>, <code>y</code>, etc., again occasionally decorated by numbers. Other single-letter variable names may be chosen if they can act as a mnemonic for their role such as using a variable named <code>p</code> for a value known to be prime.<br />
<br />
Note that these are guidelines and not rules. ''Any'' of them can and will be ignored, modified and/or abused in ''any'' given piece of Haskell code. (A quick look at the Standard Prelude as provided in the Haskell 98 Report should be convincing enough for this.)<br />
<br />
=== Tip: the -s and m- habits ===<br />
<br />
There is a variable name habit that sometimes comes with short names. Typically, if you have a thing you want to name <code>x</code>, you'll sometimes want to name lists of these <code>xs</code>. As in the plural of <code>x</code>. So if you see a name like <code>as</code> or <code>bs</code> or <code>foos</code>, it's often good to mentally read that as "aeyes" (the plural of a), "bees" (the plural of b), and "foohs" (the plural of foo). It might seem obvious to some, but it took me a while to stop asking myself in situations like this, "<code>as</code>? What the heck is aey-ess?"<br />
<br />
Similarly, another habit you might see is people who begin variable names with m-. This is probably less common, but if you see a lot of m-, it might be because of the Maybe type. Sometimes we have <code>foo</code> of type <code>Whatever</code>, and <code>mfoo</code> of type <code>Maybe Whatever</code>. Relax, this isn't [http://en.wikipedia.org/wiki/Hungarian_notation Hungarian notation]. It's not something that's used systematically, or rigidly in any way.<br />
<br />
Both of these conventions are just helpful when you have both variants floating around in the same place, that is, when you have both Whatever and [Whatever] (that would be list of whatever), <code>x</code> and <code>xs</code> is a good way to indicate that they are both the same thing, except one comes in a list. Likewise, when you have both Whatever and Maybe Whatever in the same function, <code>x</code> and <code>mx</code> are too.<br />
<br />
Finally, library functions are sometimes suffixed with "l", "r", "_", "M" or "'". What do<br />
these mean?<br />
<haskell><br />
mapM -- the 'map' function lifted into a monad. An 'M' suffix implies that the function is a<br />
-- monadic version of an equivalent pure function <br />
mapM_ -- the '_' suffix indicates that the result of this computation is discarded, and () is<br />
-- returned (by analogy with the _ pattern).<br />
foldl -- a fold that traverses its structure left to right<br />
foldr -- a fold that traverses its structure right to left<br />
foldl' -- a fold that is strict in its accumulator, "'" is used to indicate a strict variant of<br />
-- a function<br />
</haskell><br />
<br />
=== Tip: order doesn't matter ===<br />
<br />
It doesn't matter what order functions are defined in. This:<br />
<haskell><br />
foo x y z = ...<br />
<br />
bar a b = ... foo b ...<br />
</haskell><br />
is exactly equivilent to this:<br />
<haskell><br />
bar a b = ... foo b ...<br />
<br />
foo x y z = ...<br />
</haskell><br />
Functions further up can call functions that are defined lower down, and vice versa. Functions can be written in any order at all. It doesn't matter.<br />
<br />
Very important: The ''parts'' that make up a single function ''are'' in a particular order -- and that order is very important. The order in which separate functions are defined ''doesn't'' matter.<br />
<br />
:* ''scope in a nutshell''<br />
:* ''last paragraph is weak''<br />
<br />
=== Trick: use grep ===<br />
<br />
(This might seem really obvious, but it's sometimes easy to forget)<br />
<br />
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 <code>/= *xyz</code> which searches for =, an arbirtary number of spaces, and then xyz.<br />
<br />
Barring that, <code>xyz</code> might be defined in some different module in the code you downloaded. You can look for telltale signs like<br />
<haskell><br />
import Manamana (xyz)<br />
</haskell><br />
<br />
But note that sometimes programmers get lazy, and they don't specify that <code>xyz</code> should be imported. They just let rip with<br />
<haskell><br />
import Manamana<br />
</haskell><br />
<br />
So solution number 3 would be do something like<br />
<code><br />
grep xyz *.lhs *.hs<br />
</code><br />
(Note that literate programs sometimes use non-literate code, so search in both lhs AND hs)<br />
<br />
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]<br />
<br />
A fifth idea, for Hugs/WinHugs users, is to use the ":find" command, ":find xyz" will open up your text editor with the appropriate module, jumped to the correct place. GHCi users can use ":i xyz" to get the place "xyz" is defined. (It won't open an editor, though.)<br />
<br />
[[Category:Tutorials]]</div>Michael T. Richterhttps://wiki.haskell.org/index.php?title=How_to_read_Haskell&diff=13980How to read Haskell2007-07-04T02:45:53Z<p>Michael T. Richter: /* Trick: use grep */ Added information for GHCi users.</p>
<hr />
<div>This (very incomplete) tutorial is aimed at the non-Haskeller who probably doesn't care too much about trying to write code, but wants to understand it.<br />
Our adopted format is a collection of tips and tricks broken down by category. It probably isn't very important what order you read it in, but it might be good to start with the general advice. Please feel encouraged to make any complaints about Haskell on the discussion page! It will help us to improve this tutorial.<br />
<br />
Note: you should also consider having a look at [http://www.haskell.org/~pairwise/intro/intro.html Haskell for C Programmers]. It might be a good way to get over the culture shock.<br />
<br />
== General advice ==<br />
<br />
=== Tip: it's just very very concise ===<br />
<br />
One thing that can make Haskell hard to read is that Haskell code is extremely succinct. One tiny little piece of code can say a lot, so many times, when you are faced with something you don't understand, the best thing you can do is to think about it for some time. It will usually make sense after a while. The good news is that because of this succinctness, Haskell functions tend to be very small, which means that when you're trying to understand a difficult piece of Haskell, you normally do not have to look very far. It's just two sides of the same coin:<br />
* bad news: high density == spending more time per line of code<br />
* good news: succinctness == fewer lines of code to spend time on<br />
<br />
Spending on this time to get one tiny line of code may be frustrating, but it's well worth the effort, because the fact that a very small code is hard to understand probably means that it's very abstract, and the fact that it is abstract probably means that it's going to be used in many places. So understanding that one tiny line code, as painful as it may have been initially, can pay off in a big way.<br />
<br />
=== Trick: use the haddock ===<br />
<br />
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).<br />
<br />
== What does this function do? ==<br />
<br />
=== Trick: use type signatures ===<br />
<br />
When you see stuff like this<br />
<haskell><br />
map :: (a -> b) -> [a] -> [b]<br />
</haskell><br />
...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.<br />
<br />
For example, the function above takes any function that turns an 'a' into a 'b' ('a -> b') and yields a function that takes a list of a's ('[a]') and produces a list of b's ('[b]'). For example, 'sqrt' takes a number and returns the square root of that number, so 'map sqrt' takes a ''list'' of numbers and returns a ''list'' of their square roots.<br />
<br />
As another example,<br />
<haskell><br />
swap :: (a,b) -> (b,a)<br />
</haskell><br />
This takes a tuple ('(a,b)') and swaps its values around ('(b,a)').<br />
<br />
Hint: If you see '->' inside brackets, then you have a high-order function. (A function that takes another function as a parameter.) These are extremely common in Haskell.<br />
<br />
Hint: If the type has 'IO' in it anywhere, it does something to do with input/output. (Conversely, if there isn't any 'IO' in the type, the function cannot ''possibly'' perform any I/O of any kind.) Most usually the IO part comes at the end, either as 'IO ()' ("this function does some kind of input and/or output, and doesn't 'return' anything useful") or as something like 'IO Int' ("this function does input and/or output and returns an Int").<br />
<br />
:''Lots more hints could be added here. How much do we want to go into this? (Perhaps mention lists and tuples, since they have weird syntax?)''<br />
<br />
=== Tip: Haskellers love pattern matching ===<br />
<br />
<haskell><br />
head [x] = x<br />
</haskell><br />
This says that if 'head' is followed by a list containing only 1 item, label that item as 'x', and then return 'x'. Another example might be<br />
<haskell><br />
fst (x,y) = x<br />
<br />
snd (x,y) = y<br />
</haskell><br />
These functions fetch the '''f'''ir'''st''' and '''s'''eco'''nd''' items in a tuple, respectively. It should be fairly obvious how they work.<br />
<br />
:''elaborate''<br />
<br />
=== Tip: a function may be defined in more than one piece ===<br />
<br />
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...<br />
<haskell><br />
abs x | x >= 0 = x<br />
abs x = -x<br />
</haskell><br />
<br />
What gets confusing is when you look at a definition like this...<br />
<haskell><br />
foo x | blah = <br />
some enormous long thing<br />
<br />
foo x =<br />
some other enormously long thing<br />
</haskell><br />
<br />
Especially looking at the bottom bit, it's hard to remember that <code>foo</code> might have a <em>another</em> definition lurking around. Luckily, you never have to look very far, either immediately above or immediately below the other definition.<br />
<br />
(Note: some programmers will perhaps write something like <code>foo x | otherwise = ...</code>. The <code>otherwise</code> is redundant (and equal to <code>True</code>), but useful as reminder that this isn't the entire definition of <code>foo</code>)<br />
<br />
=== Tip: pattern matching and guards can be mixed and matched ===<br />
<br />
:''elaborate''<br />
<br />
<haskell><br />
combine ((f,a,b,r):(f',a',b',r'):ss)<br />
| f == f' = combine ((f,a.+a',b.+b',r+r'):ss)<br />
combine ((f,a,b,r):ss) = (f,a,b,r) : combine ss<br />
combine [] = []<br />
</haskell><br />
<br />
== What the heck is xyz? ==<br />
<br />
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.<br />
<br />
=== Tip: the smaller the name, the smaller the scope ===<br />
<br />
Do you hate the way Haskell code is littered with short, meaningless name like <code>x</code> and <code>xs</code>? When Haskell programmers use names like that, it's often for good reason.<br />
<br />
First, typically, the short, "meaningless" names are contained within a very small space. Consider this typical (and inefficient!) implementation of a prime number generator:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
<br />
The where block contains a function with strange variables like <code>x</code> and <code>xs</code> and <code>p</code>. In a more verbose language this could be difficult to read simply because it's difficult to actually find the definitions of small variables in long blocks of code. In C, for example, these would usually be defined at the top of a function which could have dozens (if not hundreds) of lines of code. Thus you might want to see <code>p</code> named as <code>known_prime</code> and <code>xs</code> named as <code>candidate_primes</code> or the like.<br />
<br />
In this code, however, there is no such need for it. <code>p</code> is (implicitly) defined in the same line of code that uses it. <code>xs</code>, too, is defined there, as is <code>x</code>. Further all three variables use a popular naming convention which appends 's' to the names of lists (or equivalents) and uses single letters for singular values. The only unusual part is the selection of the pattern <code>(p:xs)</code> in the arguments over the more common <code>(x:xs)</code>. Here the programmer is signalling (subtly) that this list head is somehow different from a normal list. Quick inspection demonstrates that <code>p</code> is guaranteed to be a prime number.<br />
<br />
The reason coding can be expressed this way in Haskell without undue confusion is because of its extreme conciseness. The habits you've had to learn to manage more verbose languages simply don't apply anymore. It takes some getting used to, but it becomes a joy one you reach that point.<br />
<br />
This, however, is not the main reason for such "meaningless" names. The real reason for such names is even deeper. The Haskell language allows for unparallelled levels of abstraction through functional composition and higher-order functions. Where in most imperative languages a "function" (or, more often, a procedure masquerading as a function) is a pretty low-level entity with very specific, tangible functionality, Haskell functions can be extremely abstract. Consider this canonical implementation of <code>foldl</code> from the Prelude:<br />
<haskell><br />
foldl :: (a -> b -> a) -> a -> [b] -> a<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
</haskell><br />
<br />
This function is a highly-abstract one. It is, in fact, an abstraction of iterating over a list and computing an aggregate result. What kind of list? Pretty much any kind. What kind of computation? Anything you'd care to name. What kind of result? Anything that matches the type of the priming value. What "meaningful" names can you apply to the variables here? Should it look something like this (elided and formed to fit a reasonable screen)?:<br />
<haskell><br />
foldl binary_operation priming_value (list_head:list_body) = <br />
foldl <br />
binary_operation <br />
(binary_operation priming_value list_head)<br />
list_body<br />
</haskell><br />
<br />
Knowing a few simple conventions of Haskell variable naming (functions progress, typically, as f, g, etc. for example) makes the first, terse version far more readable as an abstract definition than does the second, verbose version&mdash;once you get used to it.<br />
<br />
=== Tip: the -s and m- habits ===<br />
<br />
There is a variable name habit that sometimes comes with short names. Typically, if you have a thing you want to name <code>x</code>, you'll sometimes want to name lists of these <code>xs</code>. As in the plural of <code>x</code>. So if you see a name like <code>as</code> or <code>bs</code> or <code>foos</code>, it's often good to mentally read that as "aeyes" (the plural of a), "bees" (the plural of b), and "foohs" (the plural of foo). It might seem obvious to some, but it took me a while to stop asking myself in situations like this, "<code>as</code>? What the heck is aey-ess?"<br />
<br />
Similarly, another habit you might see is people who begin variable names with m-. This is probably less common, but if you see a lot of m-, it might be because of the Maybe type. Sometimes we have <code>foo</code> of type <code>Whatever</code>, and <code>mfoo</code> of type <code>Maybe Whatever</code>. Relax, this isn't [http://en.wikipedia.org/wiki/Hungarian_notation Hungarian notation]. It's not something that's used systematically, or rigidly in any way.<br />
<br />
Both of these conventions are just helpful when you have both variants floating around in the same place, that is, when you have both Whatever and [Whatever] (that would be list of whatever), <code>x</code> and <code>xs</code> is a good way to indicate that they are both the same thing, except one comes in a list. Likewise, when you have both Whatever and Maybe Whatever in the same function, <code>x</code> and <code>mx</code> are too.<br />
<br />
Finally, library functions are sometimes suffixed with "l", "r", "_", "M" or "'". What do<br />
these mean?<br />
<haskell><br />
mapM -- the 'map' function lifted into a monad. An 'M' suffix implies that the function is a<br />
-- monadic version of an equivalent pure function <br />
mapM_ -- the '_' suffix indicates that the result of this computation is discarded, and () is<br />
-- returned (by analogy with the _ pattern).<br />
foldl -- a fold that traverses its structure left to right<br />
foldr -- a fold that traverses its structure right to left<br />
foldl' -- a fold that is strict in its accumulator, "'" is used to indicate a strict variant of<br />
-- a function<br />
</haskell><br />
<br />
=== Tip: order doesn't matter ===<br />
<br />
It doesn't matter what order functions are defined in. This:<br />
<haskell><br />
foo x y z = ...<br />
<br />
bar a b = ... foo b ...<br />
</haskell><br />
is exactly equivilent to this:<br />
<haskell><br />
bar a b = ... foo b ...<br />
<br />
foo x y z = ...<br />
</haskell><br />
Functions further up can call functions that are defined lower down, and vice versa. Functions can be written in any order at all. It doesn't matter.<br />
<br />
Very important: The ''parts'' that make up a single function ''are'' in a particular order -- and that order is very important. The order in which separate functions are defined ''doesn't'' matter.<br />
<br />
:* ''scope in a nutshell''<br />
:* ''last paragraph is weak''<br />
<br />
=== Trick: use grep ===<br />
<br />
(This might seem really obvious, but it's sometimes easy to forget)<br />
<br />
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 <code>/= *xyz</code> which searches for =, an arbirtary number of spaces, and then xyz.<br />
<br />
Barring that, <code>xyz</code> might be defined in some different module in the code you downloaded. You can look for telltale signs like<br />
<haskell><br />
import Manamana (xyz)<br />
</haskell><br />
<br />
But note that sometimes programmers get lazy, and they don't specify that <code>xyz</code> should be imported. They just let rip with<br />
<haskell><br />
import Manamana<br />
</haskell><br />
<br />
So solution number 3 would be do something like<br />
<code><br />
grep xyz *.lhs *.hs<br />
</code><br />
(Note that literate programs sometimes use non-literate code, so search in both lhs AND hs)<br />
<br />
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]<br />
<br />
A fifth idea, for Hugs/WinHugs users, is to use the ":find" command, ":find xyz" will open up your text editor with the appropriate module, jumped to the correct place. GHCi users can use ":i xyz" to get the place "xyz" is defined. (It won't open an editor, though.)<br />
<br />
[[Category:Tutorials]]</div>Michael T. Richterhttps://wiki.haskell.org/index.php?title=How_to_read_Haskell&diff=13979How to read Haskell2007-07-04T02:32:54Z<p>Michael T. Richter: /* Tip: the smaller the name, the smaller the scope */ Expanded upon as requested.</p>
<hr />
<div>This (very incomplete) tutorial is aimed at the non-Haskeller who probably doesn't care too much about trying to write code, but wants to understand it.<br />
Our adopted format is a collection of tips and tricks broken down by category. It probably isn't very important what order you read it in, but it might be good to start with the general advice. Please feel encouraged to make any complaints about Haskell on the discussion page! It will help us to improve this tutorial.<br />
<br />
Note: you should also consider having a look at [http://www.haskell.org/~pairwise/intro/intro.html Haskell for C Programmers]. It might be a good way to get over the culture shock.<br />
<br />
== General advice ==<br />
<br />
=== Tip: it's just very very concise ===<br />
<br />
One thing that can make Haskell hard to read is that Haskell code is extremely succinct. One tiny little piece of code can say a lot, so many times, when you are faced with something you don't understand, the best thing you can do is to think about it for some time. It will usually make sense after a while. The good news is that because of this succinctness, Haskell functions tend to be very small, which means that when you're trying to understand a difficult piece of Haskell, you normally do not have to look very far. It's just two sides of the same coin:<br />
* bad news: high density == spending more time per line of code<br />
* good news: succinctness == fewer lines of code to spend time on<br />
<br />
Spending on this time to get one tiny line of code may be frustrating, but it's well worth the effort, because the fact that a very small code is hard to understand probably means that it's very abstract, and the fact that it is abstract probably means that it's going to be used in many places. So understanding that one tiny line code, as painful as it may have been initially, can pay off in a big way.<br />
<br />
=== Trick: use the haddock ===<br />
<br />
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).<br />
<br />
== What does this function do? ==<br />
<br />
=== Trick: use type signatures ===<br />
<br />
When you see stuff like this<br />
<haskell><br />
map :: (a -> b) -> [a] -> [b]<br />
</haskell><br />
...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.<br />
<br />
For example, the function above takes any function that turns an 'a' into a 'b' ('a -> b') and yields a function that takes a list of a's ('[a]') and produces a list of b's ('[b]'). For example, 'sqrt' takes a number and returns the square root of that number, so 'map sqrt' takes a ''list'' of numbers and returns a ''list'' of their square roots.<br />
<br />
As another example,<br />
<haskell><br />
swap :: (a,b) -> (b,a)<br />
</haskell><br />
This takes a tuple ('(a,b)') and swaps its values around ('(b,a)').<br />
<br />
Hint: If you see '->' inside brackets, then you have a high-order function. (A function that takes another function as a parameter.) These are extremely common in Haskell.<br />
<br />
Hint: If the type has 'IO' in it anywhere, it does something to do with input/output. (Conversely, if there isn't any 'IO' in the type, the function cannot ''possibly'' perform any I/O of any kind.) Most usually the IO part comes at the end, either as 'IO ()' ("this function does some kind of input and/or output, and doesn't 'return' anything useful") or as something like 'IO Int' ("this function does input and/or output and returns an Int").<br />
<br />
:''Lots more hints could be added here. How much do we want to go into this? (Perhaps mention lists and tuples, since they have weird syntax?)''<br />
<br />
=== Tip: Haskellers love pattern matching ===<br />
<br />
<haskell><br />
head [x] = x<br />
</haskell><br />
This says that if 'head' is followed by a list containing only 1 item, label that item as 'x', and then return 'x'. Another example might be<br />
<haskell><br />
fst (x,y) = x<br />
<br />
snd (x,y) = y<br />
</haskell><br />
These functions fetch the '''f'''ir'''st''' and '''s'''eco'''nd''' items in a tuple, respectively. It should be fairly obvious how they work.<br />
<br />
:''elaborate''<br />
<br />
=== Tip: a function may be defined in more than one piece ===<br />
<br />
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...<br />
<haskell><br />
abs x | x >= 0 = x<br />
abs x = -x<br />
</haskell><br />
<br />
What gets confusing is when you look at a definition like this...<br />
<haskell><br />
foo x | blah = <br />
some enormous long thing<br />
<br />
foo x =<br />
some other enormously long thing<br />
</haskell><br />
<br />
Especially looking at the bottom bit, it's hard to remember that <code>foo</code> might have a <em>another</em> definition lurking around. Luckily, you never have to look very far, either immediately above or immediately below the other definition.<br />
<br />
(Note: some programmers will perhaps write something like <code>foo x | otherwise = ...</code>. The <code>otherwise</code> is redundant (and equal to <code>True</code>), but useful as reminder that this isn't the entire definition of <code>foo</code>)<br />
<br />
=== Tip: pattern matching and guards can be mixed and matched ===<br />
<br />
:''elaborate''<br />
<br />
<haskell><br />
combine ((f,a,b,r):(f',a',b',r'):ss)<br />
| f == f' = combine ((f,a.+a',b.+b',r+r'):ss)<br />
combine ((f,a,b,r):ss) = (f,a,b,r) : combine ss<br />
combine [] = []<br />
</haskell><br />
<br />
== What the heck is xyz? ==<br />
<br />
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.<br />
<br />
=== Tip: the smaller the name, the smaller the scope ===<br />
<br />
Do you hate the way Haskell code is littered with short, meaningless name like <code>x</code> and <code>xs</code>? When Haskell programmers use names like that, it's often for good reason.<br />
<br />
First, typically, the short, "meaningless" names are contained within a very small space. Consider this typical (and inefficient!) implementation of a prime number generator:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
<br />
The where block contains a function with strange variables like <code>x</code> and <code>xs</code> and <code>p</code>. In a more verbose language this could be difficult to read simply because it's difficult to actually find the definitions of small variables in long blocks of code. In C, for example, these would usually be defined at the top of a function which could have dozens (if not hundreds) of lines of code. Thus you might want to see <code>p</code> named as <code>known_prime</code> and <code>xs</code> named as <code>candidate_primes</code> or the like.<br />
<br />
In this code, however, there is no such need for it. <code>p</code> is (implicitly) defined in the same line of code that uses it. <code>xs</code>, too, is defined there, as is <code>x</code>. Further all three variables use a popular naming convention which appends 's' to the names of lists (or equivalents) and uses single letters for singular values. The only unusual part is the selection of the pattern <code>(p:xs)</code> in the arguments over the more common <code>(x:xs)</code>. Here the programmer is signalling (subtly) that this list head is somehow different from a normal list. Quick inspection demonstrates that <code>p</code> is guaranteed to be a prime number.<br />
<br />
The reason coding can be expressed this way in Haskell without undue confusion is because of its extreme conciseness. The habits you've had to learn to manage more verbose languages simply don't apply anymore. It takes some getting used to, but it becomes a joy one you reach that point.<br />
<br />
This, however, is not the main reason for such "meaningless" names. The real reason for such names is even deeper. The Haskell language allows for unparallelled levels of abstraction through functional composition and higher-order functions. Where in most imperative languages a "function" (or, more often, a procedure masquerading as a function) is a pretty low-level entity with very specific, tangible functionality, Haskell functions can be extremely abstract. Consider this canonical implementation of <code>foldl</code> from the Prelude:<br />
<haskell><br />
foldl :: (a -> b -> a) -> a -> [b] -> a<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
</haskell><br />
<br />
This function is a highly-abstract one. It is, in fact, an abstraction of iterating over a list and computing an aggregate result. What kind of list? Pretty much any kind. What kind of computation? Anything you'd care to name. What kind of result? Anything that matches the type of the priming value. What "meaningful" names can you apply to the variables here? Should it look something like this (elided and formed to fit a reasonable screen)?:<br />
<haskell><br />
foldl binary_operation priming_value (list_head:list_body) = <br />
foldl <br />
binary_operation <br />
(binary_operation priming_value list_head)<br />
list_body<br />
</haskell><br />
<br />
Knowing a few simple conventions of Haskell variable naming (functions progress, typically, as f, g, etc. for example) makes the first, terse version far more readable as an abstract definition than does the second, verbose version&mdash;once you get used to it.<br />
<br />
=== Tip: the -s and m- habits ===<br />
<br />
There is a variable name habit that sometimes comes with short names. Typically, if you have a thing you want to name <code>x</code>, you'll sometimes want to name lists of these <code>xs</code>. As in the plural of <code>x</code>. So if you see a name like <code>as</code> or <code>bs</code> or <code>foos</code>, it's often good to mentally read that as "aeyes" (the plural of a), "bees" (the plural of b), and "foohs" (the plural of foo). It might seem obvious to some, but it took me a while to stop asking myself in situations like this, "<code>as</code>? What the heck is aey-ess?"<br />
<br />
Similarly, another habit you might see is people who begin variable names with m-. This is probably less common, but if you see a lot of m-, it might be because of the Maybe type. Sometimes we have <code>foo</code> of type <code>Whatever</code>, and <code>mfoo</code> of type <code>Maybe Whatever</code>. Relax, this isn't [http://en.wikipedia.org/wiki/Hungarian_notation Hungarian notation]. It's not something that's used systematically, or rigidly in any way.<br />
<br />
Both of these conventions are just helpful when you have both variants floating around in the same place, that is, when you have both Whatever and [Whatever] (that would be list of whatever), <code>x</code> and <code>xs</code> is a good way to indicate that they are both the same thing, except one comes in a list. Likewise, when you have both Whatever and Maybe Whatever in the same function, <code>x</code> and <code>mx</code> are too.<br />
<br />
Finally, library functions are sometimes suffixed with "l", "r", "_", "M" or "'". What do<br />
these mean?<br />
<haskell><br />
mapM -- the 'map' function lifted into a monad. An 'M' suffix implies that the function is a<br />
-- monadic version of an equivalent pure function <br />
mapM_ -- the '_' suffix indicates that the result of this computation is discarded, and () is<br />
-- returned (by analogy with the _ pattern).<br />
foldl -- a fold that traverses its structure left to right<br />
foldr -- a fold that traverses its structure right to left<br />
foldl' -- a fold that is strict in its accumulator, "'" is used to indicate a strict variant of<br />
-- a function<br />
</haskell><br />
<br />
=== Tip: order doesn't matter ===<br />
<br />
It doesn't matter what order functions are defined in. This:<br />
<haskell><br />
foo x y z = ...<br />
<br />
bar a b = ... foo b ...<br />
</haskell><br />
is exactly equivilent to this:<br />
<haskell><br />
bar a b = ... foo b ...<br />
<br />
foo x y z = ...<br />
</haskell><br />
Functions further up can call functions that are defined lower down, and vice versa. Functions can be written in any order at all. It doesn't matter.<br />
<br />
Very important: The ''parts'' that make up a single function ''are'' in a particular order -- and that order is very important. The order in which separate functions are defined ''doesn't'' matter.<br />
<br />
:* ''scope in a nutshell''<br />
:* ''last paragraph is weak''<br />
<br />
=== Trick: use grep ===<br />
<br />
(This might seem really obvious, but it's sometimes easy to forget)<br />
<br />
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 <code>/= *xyz</code> which searches for =, an arbirtary number of spaces, and then xyz.<br />
<br />
Barring that, <code>xyz</code> might be defined in some different module in the code you downloaded. You can look for telltale signs like<br />
<haskell><br />
import Manamana (xyz)<br />
</haskell><br />
<br />
But note that sometimes programmers get lazy, and they don't specify that <code>xyz</code> should be imported. They just let rip with<br />
<haskell><br />
import Manamana<br />
</haskell><br />
<br />
So solution number 3 would be do something like<br />
<code><br />
grep xyz *.lhs *.hs<br />
</code><br />
(Note that literate programs sometimes use non-literate code, so search in both lhs AND hs)<br />
<br />
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]<br />
<br />
A fifth idea, for Hugs/WinHugs users, is to use the ":find" command, ":find xyz" will open up your text editor with the appropriate module, jumped to the correct place.<br />
<br />
[[Category:Tutorials]]</div>Michael T. Richterhttps://wiki.haskell.org/index.php?title=How_to_read_Haskell&diff=13978How to read Haskell2007-07-03T22:42:26Z<p>Michael T. Richter: Reformatted so people don't have to horizontally scroll.</p>
<hr />
<div>This (very incomplete) tutorial is aimed at the non-Haskeller who probably doesn't care too much about trying to write code, but wants to understand it.<br />
Our adopted format is a collection of tips and tricks broken down by category. It probably isn't very important what order you read it in, but it might be good to start with the general advice. Please feel encouraged to make any complaints about Haskell on the discussion page! It will help us to improve this tutorial.<br />
<br />
Note: you should also consider having a look at [http://www.haskell.org/~pairwise/intro/intro.html Haskell for C Programmers]. It might be a good way to get over the culture shock.<br />
<br />
== General advice ==<br />
<br />
=== Tip: it's just very very concise ===<br />
<br />
One thing that can make Haskell hard to read is that Haskell code is extremely succinct. One tiny little piece of code can say a lot, so many times, when you are faced with something you don't understand, the best thing you can do is to think about it for some time. It will usually make sense after a while. The good news is that because of this succinctness, Haskell functions tend to be very small, which means that when you're trying to understand a difficult piece of Haskell, you normally do not have to look very far. It's just two sides of the same coin:<br />
* bad news: high density == spending more time per line of code<br />
* good news: succinctness == fewer lines of code to spend time on<br />
<br />
Spending on this time to get one tiny line of code may be frustrating, but it's well worth the effort, because the fact that a very small code is hard to understand probably means that it's very abstract, and the fact that it is abstract probably means that it's going to be used in many places. So understanding that one tiny line code, as painful as it may have been initially, can pay off in a big way.<br />
<br />
=== Trick: use the haddock ===<br />
<br />
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).<br />
<br />
== What does this function do? ==<br />
<br />
=== Trick: use type signatures ===<br />
<br />
When you see stuff like this<br />
<haskell><br />
map :: (a -> b) -> [a] -> [b]<br />
</haskell><br />
...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.<br />
<br />
For example, the function above takes any function that turns an 'a' into a 'b' ('a -> b') and yields a function that takes a list of a's ('[a]') and produces a list of b's ('[b]'). For example, 'sqrt' takes a number and returns the square root of that number, so 'map sqrt' takes a ''list'' of numbers and returns a ''list'' of their square roots.<br />
<br />
As another example,<br />
<haskell><br />
swap :: (a,b) -> (b,a)<br />
</haskell><br />
This takes a tuple ('(a,b)') and swaps its values around ('(b,a)').<br />
<br />
Hint: If you see '->' inside brackets, then you have a high-order function. (A function that takes another function as a parameter.) These are extremely common in Haskell.<br />
<br />
Hint: If the type has 'IO' in it anywhere, it does something to do with input/output. (Conversely, if there isn't any 'IO' in the type, the function cannot ''possibly'' perform any I/O of any kind.) Most usually the IO part comes at the end, either as 'IO ()' ("this function does some kind of input and/or output, and doesn't 'return' anything useful") or as something like 'IO Int' ("this function does input and/or output and returns an Int").<br />
<br />
:''Lots more hints could be added here. How much do we want to go into this? (Perhaps mention lists and tuples, since they have weird syntax?)''<br />
<br />
=== Tip: Haskellers love pattern matching ===<br />
<br />
<haskell><br />
head [x] = x<br />
</haskell><br />
This says that if 'head' is followed by a list containing only 1 item, label that item as 'x', and then return 'x'. Another example might be<br />
<haskell><br />
fst (x,y) = x<br />
<br />
snd (x,y) = y<br />
</haskell><br />
These functions fetch the '''f'''ir'''st''' and '''s'''eco'''nd''' items in a tuple, respectively. It should be fairly obvious how they work.<br />
<br />
:''elaborate''<br />
<br />
=== Tip: a function may be defined in more than one piece ===<br />
<br />
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...<br />
<haskell><br />
abs x | x >= 0 = x<br />
abs x = -x<br />
</haskell><br />
<br />
What gets confusing is when you look at a definition like this...<br />
<haskell><br />
foo x | blah = <br />
some enormous long thing<br />
<br />
foo x =<br />
some other enormously long thing<br />
</haskell><br />
<br />
Especially looking at the bottom bit, it's hard to remember that <code>foo</code> might have a <em>another</em> definition lurking around. Luckily, you never have to look very far, either immediately above or immediately below the other definition.<br />
<br />
(Note: some programmers will perhaps write something like <code>foo x | otherwise = ...</code>. The <code>otherwise</code> is redundant (and equal to <code>True</code>), but useful as reminder that this isn't the entire definition of <code>foo</code>)<br />
<br />
=== Tip: pattern matching and guards can be mixed and matched ===<br />
<br />
:''elaborate''<br />
<br />
<haskell><br />
combine ((f,a,b,r):(f',a',b',r'):ss)<br />
| f == f' = combine ((f,a.+a',b.+b',r+r'):ss)<br />
combine ((f,a,b,r):ss) = (f,a,b,r) : combine ss<br />
combine [] = []<br />
</haskell><br />
<br />
== What the heck is xyz? ==<br />
<br />
One problem you might face when reading Haskell code is figuring out some cryptic entity like <code>xyz</code> is.<br />
<br />
=== Tip: the smaller the name, the smaller the scope ===<br />
<br />
Do you hate the way Haskell code is littered with short, meaningless name like <code>x</code> and <code>xs</code>? When Haskell programmers use names like that, it's often for good reason.<br />
<br />
:''elaborate: (1) scope size, (2) abstraction means it would be silly to give long names''<br />
<br />
=== Tip: the -s and m- habits ===<br />
<br />
There is a variable name habit that sometimes comes with short names. Typically, if you have a thing you want to name <code>x</code>, you'll sometimes want to name lists of these <code>xs</code>. As in the plural of <code>x</code>. So if you see a name like <code>as</code> or <code>bs</code> or <code>foos</code>, it's often good to mentally read that as "aeyes" (the plural of a), "bees" (the plural of b), and "foohs" (the plural of foo). It might seem obvious to some, but it took me a while to stop asking myself in situations like this, "<code>as</code>? What the heck is aey-ess?"<br />
<br />
Similarly, another habit you might see is people who begin variable names with m-. This is probably less common, but if you see a lot of m-, it might be because of the Maybe type. Sometimes we have <code>foo</code> of type <code>Whatever</code>, and <code>mfoo</code> of type <code>Maybe Whatever</code>. Relax, this isn't [http://en.wikipedia.org/wiki/Hungarian_notation Hungarian notation]. It's not something that's used systematically, or rigidly in any way.<br />
<br />
Both of these conventions are just helpful when you have both variants floating around in the same place, that is, when you have both Whatever and [Whatever] (that would be list of whatever), <code>x</code> and <code>xs</code> is a good way to indicate that they are both the same thing, except one comes in a list. Likewise, when you have both Whatever and Maybe Whatever in the same function, <code>x</code> and <code>mx</code> are too.<br />
<br />
Finally, library functions are sometimes suffixed with "l", "r", "_", "M" or "'". What do<br />
these mean?<br />
<haskell><br />
mapM -- the 'map' function lifted into a monad. An 'M' suffix implies that the function is a<br />
-- monadic version of an equivalent pure function <br />
mapM_ -- the '_' suffix indicates that the result of this computation is discarded, and () is<br />
-- returned (by analogy with the _ pattern).<br />
foldl -- a fold that traverses its structure left to right<br />
foldr -- a fold that traverses its structure right to left<br />
foldl' -- a fold that is strict in its accumulator, "'" is used to indicate a strict variant of<br />
-- a function<br />
</haskell><br />
<br />
=== Tip: order doesn't matter ===<br />
<br />
It doesn't matter what order functions are defined in. This:<br />
<haskell><br />
foo x y z = ...<br />
<br />
bar a b = ... foo b ...<br />
</haskell><br />
is exactly equivilent to this:<br />
<haskell><br />
bar a b = ... foo b ...<br />
<br />
foo x y z = ...<br />
</haskell><br />
Functions further up can call functions that are defined lower down, and vice versa. Functions can be written in any order at all. It doesn't matter.<br />
<br />
Very important: The ''parts'' that make up a single function ''are'' in a particular order -- and that order is very important. The order in which separate functions are defined ''doesn't'' matter.<br />
<br />
:* ''scope in a nutshell''<br />
:* ''last paragraph is weak''<br />
<br />
=== Trick: use grep ===<br />
<br />
(This might seem really obvious, but it's sometimes easy to forget)<br />
<br />
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 <code>/= *xyz</code> which searches for =, an arbirtary number of spaces, and then xyz.<br />
<br />
Barring that, <code>xyz</code> might be defined in some different module in the code you downloaded. You can look for telltale signs like<br />
<haskell><br />
import Manamana (xyz)<br />
</haskell><br />
<br />
But note that sometimes programmers get lazy, and they don't specify that <code>xyz</code> should be imported. They just let rip with<br />
<haskell><br />
import Manamana<br />
</haskell><br />
<br />
So solution number 3 would be do something like<br />
<code><br />
grep xyz *.lhs *.hs<br />
</code><br />
(Note that literate programs sometimes use non-literate code, so search in both lhs AND hs)<br />
<br />
A fourth idea, if you can't find something, is to look it up in [http://haskell.org/hoogle/ Hoogle]<br />
<br />
A fifth idea, for Hugs/WinHugs users, is to use the ":find" command, ":find xyz" will open up your text editor with the appropriate module, jumped to the correct place.<br />
<br />
[[Category:Tutorials]]</div>Michael T. Richterhttps://wiki.haskell.org/index.php?title=HaskellWiki:Community&diff=13863HaskellWiki:Community2007-06-29T07:55:48Z<p>Michael T. Richter: Printable versions?</p>
<hr />
<div>This page is for the community of those editing this web-site.<br />
<br />
== Licensing ==<br />
<br />
Please have a look at the [[HaskellWiki:Licensing|licensing information]].<br />
<br />
== Subpages ==<br />
<br />
Subpage support is switched on for all namespaces apart from ''Image:'' and ''MediaWiki:''.<br />
<br />
== Special pages ==<br />
<br />
Here are some special pages that may come in handy:<br />
*[[Haskell|Main page]]<br />
*[[Special:Allpages|All pages of this wiki]]<br />
*[[Special:Recentchanges|Recent changes]]<br />
*[[Special:Watchlist|Recent changes on articles you are “watching”]]<br />
*[[Special:Random|Random article]]<br />
*[[Special:Specialpages|All special pages]]<br />
*[[MediaWiki:Quiet.css|CSS style sheet]]<br />
<br />
== Syntax highlighting ==<br />
<br />
See [[HaskellWiki:Syntax highlighting]].<br />
<br />
== Spammers ==<br />
<br />
Spammers are creating accounts and adding hidden links. Thanks to those who are reverting the spam.<br />
<br />
I'm looking at Captcha extensions for MediaWiki. I want to put a Captcha just on new account creation: hopefully that will be enough. &mdash;[[User:Ashley Y|Ashley Y]] 23:15, 10 March 2006 (UTC)<br />
<br />
:Is there a way to revert the spammers changes easily, other than modifying the page in the reverse way? A kind of revert command that really does just roll back the history. --[[User:NeilMitchell|Neil Mitchell]] 10:05, 11 March 2006 (UTC)<br />
<br />
::The easiest way is to edit the previous version and save it, I think. &mdash;[[User:Ashley Y|Ashley Y]] 07:50, 12 March 2006 (UTC)<br />
<br />
:::If you click on the 'diff' link in RecentChanges, there is a [revert] button (maybe only for administrators). -- [[User:EricKow|kowey]] 13:23, 20 April 2007 (UTC)<br />
<br />
=== Now logging IP addresses ===<br />
<br />
I am now logging IP addresses of changes. I can now use this to block the IP addresses of spammers. &mdash;[[User:Ashley Y|Ashley Y]] 07:50, 12 March 2006 (UTC)<br />
<br />
== Style Help ==<br />
<br />
I think the style (which I copied from the original haskell.org pages) could use improvement. Is there anyone interested in doing this? The main file is [[MediaWiki:Quiet.css]] (see [[HaskellWiki:Site software]] for others). More than one person would be ideal. If there's interest, I'll unprotect the page, and people can edit it and discuss changes on the associated talk page as usual. &mdash;[[User:Ashley Y|Ashley Y]] 02:11, 16 November 2006 (UTC)<br />
<br />
=== Numbered headings ===<br />
<br />
I have turned on numbered headings for non-logged-in viewers, since Simon PJ requested it. Logged-in users will have to turn it on in Preferences -> Misc. I'm not sure if it's an improvement, however. &mdash;[[User:Ashley Y|Ashley Y]] 02:41, 16 November 2006 (UTC)<br />
<br />
== Printable version and skins ==<br />
<br />
Some of the skins support a "printable version" link on pages. Most do not (including the default one). Is it possible to turn "printable version" links on all skins without a huge amount of work and effort?</div>Michael T. Richter