﻿

More on functions (Solutions)

## Contents

As functions are absolutely essential to functional programming, there are several nice features that make using functions easier.

## let and where revisited

First, a few extra words about `let` and `where`, which are useful to make local function definitions. A function like `addStr` from the List processing chapter...

```addStr :: Float -> String -> Float

sumStr :: [String] -> Float
```

... can be rewritten using local bindings in order to reduce clutter on the top level of the program (which makes a lot of sense assuming `addStr` is only used as part of `sumStr`). We can do that either with a let binding...

```sumStr =
```

... or with a `where` clause...

```sumStr = foldl addStr 0.0
```

... and the difference appears to be only one of style - bindings coming either before or after the rest of the definition. The relation between `let` and `where`, however, is similar to the one between `if` and guards, in that a let...in construct is an expression while a `where` clause isn't. That means we can embed a `let` binding, but not a `where` clause, in a complex expression in this way:

```f x =
if x > 0
then (let lsq = (log x) ^ 2 in tan lsq) * sin x
else 0
```

The expression within the outer parentheses is self-contained, and evaluates to the tangent of the square of the logarithm of `x`. Note that the scope of `lsq` does not extend beyond the parentheses; and therefore changing the then-branch to

```        then (let lsq = (log x) ^ 2 in tan lsq) * (sin x + lsq)
```

wouldn't work - we would have to drop the parentheses around the `let`.

Still, `where` clauses can be incorporated into `case` expressions:

```describeColour c =
"This colour "
++ case c of
Black -> "is black"
White -> "is white"
RGB red green blue -> " has an average of the components of " ++ show av
where av = (red + green + blue) `div` 3
++ ", yeah?"
```

In this example, the indentation of the where clause sets the scope of the av variable so that it only exists as far as the RGB red green blue case is concerned. Placing it at the same indentation of the cases would make it available for all cases. Here is an example with guards:

```doStuff :: Int -> String
doStuff x
| x < 3     = report "less than three"
| otherwise = report "normal"
where
report y = "the input is " ++ y
```

Note that since there is one equals sign for each guard there is no place we could put a `let` expression which would be in scope of all guards, as the `where` clause is. Here we have a situation in which `where` is particularly convenient.

## Anonymous Functions - lambdas

An alternative to creating a private named function like `addStr` is to create an anonymous function, also known as a `lambda function`. For example, `sumStr` could have been defined like this:

```sumStr = foldl (\x str -> x + read str) 0.0
```

The expression in the parentheses is a lambda function. The backslash is used as the nearest ASCII equivalent to the Greek letter lambda (λ). This example is a lambda function with two arguments, `x` and `str`, which evaluates to "x + read str". So, the `sumStr` presented just above is precisely the same as the one that used `addStr` in a let binding.

Lambdas are handy for writing one-off functions to be used with maps, folds and their siblings, especially where the function in question is simple - as cramming complicated expressions in a lambda can hurt readability.

Since variables are being bound in a lambda expression (to the arguments, just like in a regular function definition), pattern matching can be used in them as well. A trivial example would be redefining `tail` with a lambda:

```tail' = (\(_:xs) -> xs)
```

## Operators and sections

As noted in a number of occasions, operators such as the arithmetical ones can be used surrounded in parentheses and used prefix, like other functions:

```2 + 4
(+) 2 4
```

Generalizing that point, we can now define the term "operator" clearly: as far as Haskell is concerned it's a function with two arguments and a name consisting entirely of non-alphanumeric characters. Unlike other functions, operators can be used infix straight away. We can define new operators in the usual way; just don't use any alphanumeric characters. For example, here's the set-difference definition from `Data.List`:

```(\\) :: (Eq a) => [a] -> [a] -> [a]
xs \\ ys = foldl (\zs y -> delete y zs) xs ys
```

Note that, aside from just using operators infix, you can define them infix as well. This is a point that most newcomers to Haskell miss. I.e., although one could have written:

```(\\) xs ys = foldl (\zs y -> delete y zs) xs ys
```

It's more common to define operators infix. However, do note that in type declarations, you have to write them with the parentheses.

Sections are a nifty piece of syntactical sugar that can be used with operators. An operator within parentheses and flanked by one of its arguments...

```(2+) 4
(+4) 2
```

... is a new function in its own right. `(2+)`, for instance, has the type `(Num a) => a -> a`. We can pass sections to other functions, e.g. `map (+2) [1..4] == [3..6]`. For another example, we can add an extra flourish to the `multiplyList` function we wrote back in More about lists:

```multiplyList :: Integer -> [Integer] -> [Integer]
multiplyList m = map (m*)
```

If you have a "normal", prefix function, and want to use it as an operator, simply surround it by backticks:

```1 `elem` [1..4]
```

This is called making the function infix. It's normally done for readability purposes: `1 `elem` [1..4]` reads better than `elem 1 [1..4]`. You can also define functions infix:

```elem :: (Eq a) => a -> [a] -> Bool
x `elem` xs = any (==x) xs
```

But once again notice that in the type signature you have to use the prefix style.

Sections even work with infix functions:

```(1 `elem`) [1..4]
(`elem` [1..4]) 1
```

You can only make binary functions (that is, those that take two arguments) infix. Think about the functions you use, and see which ones would read better if you used them infix.

Exercises
• Lambdas are a nice way to avoid defining unnecessary separate functions. Convert the following let- or where-bindings to lambdas:
• `map f xs where f x = x * 2 + 3`
• `let f x y = read x + y in foldr f 1 xs`
• Sections are just syntactic sugar for lambda operations. I.e. `(+2)` is equivalent to `\x -> x + 2`. What would the following sections 'desugar' to? What would be their types?
• `(4+)`
• `(1 `elem`)`
• `(`notElem` "abc")`
 More on functions Solutions to exercises Elementary Haskell edit this chapter Haskell edit book structure