Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [3]

By Root 396 0
on any two items that can be compared, with one catch: they both have to be of the same type. For instance, if we tried entering True == 5, GHCi would complain.

Note

5 + 4.0 is a valid expression, because although 4.0 isn’t an integer, 5 is sneaky and can act like either an integer or a floating-point number. In this case, 5 adapts to match the type of the floating-point value 4.0.

We’ll take a closer look at types a bit later.

Calling Functions


You may not have realized it, but we’ve actually been using functions this whole time. For instance, * is a function that takes two numbers and multiplies them. As you’ve seen, we apply (or call) it by sandwiching it between the two numbers we want to multiply. This is called an infix function.

Most functions, however, are prefix functions. When calling prefix functions in Haskell, the function name comes first, then a space, then its parameters (also separated by spaces). As an example, we’ll try calling one of the most boring functions in Haskell, succ:

ghci> succ 8

9

The succ function takes one parameter that can be anything that has a well-defined successor, and returns that value. The successor of an integer value is just the next higher number.

Now let’s call two prefix functions that take multiple parameters, min and max:

ghci> min 9 10

9

ghci> min 3.4 3.2

3.2

ghci> max 100 101

101

The min and max functions each take two parameters that can be put in some order (like numbers!), and they return the one that’s smaller or larger, respectively.

Function application has the highest precedence of all the operations in Haskell. In other words, these two statements are equivalent.

ghci> succ 9 + max 5 4 + 1

16

ghci> (succ 9) + (max 5 4) + 1

16

This means that if we want to get the successor of 9 * 10, we couldn’t simply write

ghci> succ 9 * 10

Because of the precedence of operations, this would evaluate as the successor of 9 (which is 10) multiplied by 10, yielding 100. To get the result we want, we need to instead enter

ghci> succ (9 * 10)

This returns 91.

If a function takes two parameters, we can also call it as an infix function by surrounding its name with backticks (`). For instance, the div function takes two integers and executes an integral division, as follows:

ghci> div 92 10

9

However, when we call it like that, there may be some confusion as to which number is being divided by which. By using backticks, we can call it as an infix function, and suddenly it seems much clearer:

ghci> 92 `div` 10

9

Many programmers who are used to imperative languages tend to stick to the notion that parentheses should denote function application, and they have trouble adjusting to the Haskell way of doing things. Just remember, if you see something like bar (bar 3), it means that we’re first calling the bar function with 3 as the parameter, then passing that result to the bar function again. The equivalent expression in C would be something like bar(bar(3)).

Baby's First Functions

The syntax of a function definition is similar to that of a function call: the function name is followed by parameters, which are separated by spaces. But then the parameter list is followed by the = operator, and the code that makes up the body of the function follows that.

As an example, we’ll write a simple function that takes a number and multiplies it by two. Open up your favorite text editor and type in the following:

doubleMe x = x + x

Save this file as baby.hs. Now run ghci, making sure that baby.hs is in your current directory. Once in GHCi, enter :l baby to load the file. Now we can play with our new function:

ghci> :l baby

[1 of 1] Compiling Main ( baby.hs, interpreted )

Ok, modules loaded: Main.

ghci> doubleMe 9

18

ghci> doubleMe 8.3

16.6

Because + works on integers as well as on floating point numbers (indeed, on anything that can be considered a number), our function also works with any of these types.

Now let’s make a function that takes two numbers, multiplies each by two, then adds them together. Append the following code to baby.hs:

Return Main Page Previous Page Next Page

®Online Book Reader