# Difference between revisions of "Common Misunderstandings"

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 12: | ||

</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>. |

− | <code> |
||

+ | <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 30: | ||

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

# 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.

## 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 `then`

and `else`

must be indented deeper than the `if`

statement:

```
if boolean
then expr1
else expr2
```

Or they can be on the same line as the if:

```
if boolean then expr1 else expr2
```

## 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;
```

The above is valid, though not common, C code. It states that if `b`

is true then `x = y`

otherwise `x = z`

. Notice how this makes no sense without `z`

. Similarly, in Haskell an `if`

/`then`

makes no sense without an `else`

.

```
let x = if b then y -- compare to x = b ? y
```

What is `x`

when `b`

is false? One should also recognize that the types returned by the `then`

and `else`

branches must match due to Haskells strong and static type system.

When `if`

is used for sequencing IO it is not uncommon to see an `else`

that returns a null value:

```
main = do
startNetwork <- askUser "Network? "
if startNetwork
then do iface <- initNetworkInterface
handlePackets iface
else return ()
```

Such uses can be more succinct if they use the `when`

keyword:

```
main = do
startNetwork <- askUser "Network? "
when startNetwork (do
iface <- initNetworkInterface
handlePackets iface )
```

**do** Notation

If the do notation page ever exists I'll advice you to check it out. Until then, understand that a missing `do`

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 `if`

or `case`

) must have their own `do`

, 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.