Online Book Reader

Home Category

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

By Root 444 0
sections. To section an infix function, simply surround it with parentheses and supply a parameter on only one side. That creates a function that takes one parameter and then applies it to the side that’s missing an operand. Here’s an insultingly trivial example:

divideByTen :: (Floating a) => a -> a

divideByTen = (/10)

As you can see in the following code, calling divideByTen 200 is equivalent to calling 200 / 10 or (/10) 200:

ghci> divideByTen 200

20.0

ghci> 200 / 10

20.0

ghci> (/10) 200

20.0

Let’s look at another example. This function checks if a character supplied to it is an uppercase letter:

isUpperAlphanum :: Char -> Bool

isUpperAlphanum = (`elem` ['A'..'Z'])

The only thing to watch out for with sections is when you’re using the - (negative or minus) operator. From the definition of sections, (-4) would result in a function that takes a number and subtracts 4 from it. However, for convenience, (-4) means negative four. So if you want to make a function that subtracts 4 from the number it gets as a parameter, you can partially apply the subtract function like so: (subtract 4).

Printing Functions


So far, we’ve bound our partially applied functions to names and then supplied the remaining parameters to view the results. However, we never tried to print the functions themselves to the terminal. Let’s give that a go then, shall we? What happens if we try entering multThree 3 4 into GHCi, instead of binding it to a name with a let or passing it to another function?

ghci> multThree 3 4

:1:0:

No instance for (Show (a -> a))

arising from a use of `print' at :1:0-12

Possible fix: add an instance declaration for (Show (a -> a))

In the expression: print it

In a 'do' expression: print it

GHCi is telling us that the expression produced a function of type a -> a, but it doesn’t know how to print it to the screen. Functions aren’t instances of the Show type class, so we can’t get a neat string representation of a function. This is different, for example, than when we enter 1 + 1 at the GHCi prompt. In that case, GHCi calculates 2 as the result, and then calls show on 2 to get a textual representation of that number. The textual representation of 2 is just the string "2", which is then printed to the screen.

Note

Make sure you thoroughly understand how curried functions and partial application work, because they’re really important!

Some Higher-Orderism Is in Order

In Haskell, functions can take other functions as parameters, and as you’ve seen, they can also return functions as return values. To demonstrate this concept, let’s write a function that takes a function, and then applies it twice to some value:

applyTwice :: (a -> a) -> a -> a

applyTwice f x = f (f x)

Notice the type declaration. For our earlier examples, we didn’t need parentheses when declaring function types, because -> is naturally right-associative. However, here parentheses are mandatory. They indicate that the first parameter is a function that takes one parameter and returns a value of the same type (a -> a). The second parameter is something of type a, and the return value’s type is also a. Notice that it doesn’t matter what type a is—it can be Int, String, or whatever—but all the values must be the same type.

Note

You now know that under the hood, functions that seem to take multiple parameters are actually taking a single parameter and returning a partially applied function. However, to keep things simple, I’ll continue to say that a given function takes multiple parameters.

The body of the applyTwice function is very simple. We just use the parameter f as a function, applying x to it by separating the f and x with a space. We then apply the result to f again. Here are some examples of the function in action:

ghci> applyTwice (+3) 10

16

ghci> applyTwice (++ " HAHA") "HEY"

"HEY HAHA HAHA"

ghci> applyTwice ("HAHA " ++) "HEY"

"HAHA HAHA HEY"

ghci> applyTwice (multThree 2 2) 9

144

ghci> applyTwice (3:) [1]

[3,3,1]

The awesomeness and usefulness of partial application is evident. If

Return Main Page Previous Page Next Page

®Online Book Reader