Learn You a Haskell for Great Good! - Miran Lipovaca [28]
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
No instance for (Show (a -> a)) arising from a use of `print' at 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