Common Misunderstandings
From HaskellWiki
(Difference between revisions)
m |
|||
| Line 3: | Line 3: | ||
== Indentation == | == Indentation == | ||
| - | Perhaps the first trip-up - you might understand that indentation defines where a code block starts and the lack of an equal amount of indentation indicates the previous code block ended. What some miss is that <hask>then</hask> and <hask>else</hask> must be indented deeper than the <hask>if</hask> statement | + | Perhaps the first trip-up - you might understand that indentation defines where a code block starts and the lack of an equal amount of indentation indicates the previous code block ended. What some miss is that <hask>then</hask> and <hask>else</hask> must be indented deeper than the <hask>if</hask> statement: |
| + | |||
| + | <haskell> | ||
| + | if boolean | ||
| + | then expr1 | ||
| + | else expr2 | ||
| + | </haskell> | ||
| + | |||
| + | Or they can be on the same line as the if: | ||
| + | |||
| + | <haskell> | ||
| + | if boolean then expr1 else expr2 | ||
| + | </haskell> | ||
== If / Then / Else == | == If / Then / Else == | ||
| Line 12: | Line 24: | ||
</code> | </code> | ||
| - | The above is valid, though not common, C code. It states that if <code>b</code> is true then <code>x = y</code> otherwise <code>x = z</code>. Notice how this makes no sense without <code>z</code> | + | The above is valid, though not common, C code. It states that if <code>b</code> is true then <code>x = y</code> otherwise <code>x = z</code>. Notice how this makes no sense without <code>z</code>. Similarly, in Haskell an <hask>if</hask>/<hask>then</hask> makes no sense without an <hask>else</hask>. |
| - | < | + | <haskell> |
| - | x = b ? y | + | let x = if b then y -- compare to x = b ? y |
| - | </ | + | </haskell> |
What is <code>x</code> when <code>b</code> is false? One should also recognize that the types returned by the <hask>then</hask> and <hask>else</hask> branches must match due to Haskells strong and static type system. | What is <code>x</code> when <code>b</code> is false? One should also recognize that the types returned by the <hask>then</hask> and <hask>else</hask> branches must match due to Haskells strong and static type system. | ||
| Line 30: | Line 42: | ||
else return () | else return () | ||
</haskell> | </haskell> | ||
| + | |||
| + | Such uses can be more succinct if they use the <hask>when</hask> keyword: | ||
| + | |||
| + | <haskell> | ||
| + | main = do | ||
| + | startNetwork <- askUser "Network? " | ||
| + | when startNetwork (do | ||
| + | iface <- initNetworkInterface | ||
| + | handlePackets iface ) | ||
| + | </haskell> | ||
| + | |||
== '''do''' Notation == | == '''do''' Notation == | ||
| - | If the [[do notation]] page ever exists I'll advice you to check it out. Until then, understand that a missing <hask>do</hask> from the top of a function or code block can result in your compiler giving an error message citing a | + | If the [[do notation]] page ever exists I'll advice you to check it out. Until then, understand that a missing <hask>do</hask> from the top of a function or code block can result in your compiler giving an error message citing a much later line number. Also, any new blocks (ex: from an <hask>if</hask> or <hask>case</hask>) must have their own <hask>do</hask>, even if the higher level code block already had one. |
| - | + | Sorry this isn't the full picture - for an inverse point of view see [[do notation considered harmful]]. | |
Revision as of 19:24, 15 March 2008
Contents |
1 Common Mistakes and Incorrect Beliefs By Haskell Beginners
People going from zero to Haskell are likely gain a misunderstanding or miss a point that isn't stressed enough. Here are some mistakes that have been observed from multiple sources.
1.1 Indentation
Perhaps the first trip-up - you might understand that indentation defines where a code block starts and the lack of an equal amount of indentation indicates the previous code block ended. What some miss is thatthen
else
if
if boolean then expr1 else expr2
Or they can be on the same line as the if:
if boolean then expr1 else expr2
1.2 If / Then / Else
if-then statements must always include an 'else' portion. It might be best not to think of if-then-else as flow control, as in most imperative languages, but think of it as construction of a value using a well formed expression.
x = b ? y : z;
b is true then x = y otherwise x = z. Notice how this makes no sense without z. Similarly, in Haskell an if
then
else
let x = if b then y -- compare to x = b ? y
x when b is false? One should also recognize that the types returned by the then
else
if
else
main = do startNetwork <- askUser "Network? " if startNetwork then do iface <- initNetworkInterface handlePackets iface else return ()
when
main = do startNetwork <- askUser "Network? " when startNetwork (do iface <- initNetworkInterface handlePackets iface )
1.3 do Notation
If the do notation page ever exists I'll advice you to check it out. Until then, understand that a missingdo
if
case
do
Sorry this isn't the full picture - for an inverse point of view see do notation considered harmful.
