Please Buy now at Leanpub

Written and illustrated by GetContented.

Published on 2017-12-25.

Previous chapter: 5. Function Magic

6. Sockets & Plugs

... 6.1. Reusability

... 6.2. Functions are Values

... 6.3. Plugging Values into Functions

... 6.4. Defining Functions

... 6.5. Operator Sections

... 6.6. What is commutivity?

... 6.7. Homework

Next chapter: 7. Output Other Things

In this chapter, we'll explain another way that might help you to think about functions work when they’re used. All of these views of functions can help you to get a rounded idea of how to use them well. We're spending so much time on this because it's the underpinning of everything in Haskell.

We could think of them like they were electronic devices, waiting to have something plugged into them. Depending on what you plug in, you will get a different result.

Functions are one of the most basic ways to re-use expressions in a program. They save us repeating ourselves as we write programs. Functions take **variables** or **parameters** that can have different values (of a type) for each new time the function is applied.

Functions are also themselves values, but they are a special kind of mapping-value from values to other values.

This is why `putStrLn "hi"`

means to “apply the `putStrLn`

function to the `String`

value `"hi"`

.

Another way to think of it is that `putStrLn`

makes a kind of mapping between any `String`

value to a corresponding `IO ()`

value.

Let’s imagine there’s a function called `plus5`

which takes a whole number as its single parameter. When we give it a value, the result is whatever its input is, but 5 more.

If we were applying this function to the number `53`

, for example, we would write the function application `plus5 53`

.

```
-- we apply the function plus5
-- to the number 53
plus5 53
```

Above, we show this function as a machine box with a plug and a screen that shows the “answer”.

`Int`

is one of Haskell’s names for the type of whole numbers; both negative and positive. The mathematical name for a whole number is integer, which comes from latin and means “entire”.

The function’s type is written in Haskell as `Int -> Int`

, which means “the type of all functions that map from an `Int`

value, to another `Int`

value”.

We can also say that `Int -> Int`

is “an `Int`

that is a function of another `Int`

”. Its value isn’t just an `Int`

until you “give” it an `Int`

.

So in the graphic, we “plug” `53`

into this `plus5`

box, and it displays `58`

. Comparing our graphic with the way **function application** is actually written, we can see it’s reversed. In Haskell, as well as in Math, we usually plug values in to the **right** of the function, (or sometimes, with operators, the left and right), whereas in our box graphic, or with audio equipment, we’re plugging values in on the left of the boxes (which represent functions).

This is an important point. The way people think and do things is often put a different way around compared to the way you have to write things in Haskell. This is often the same thing with Math. In Math and Haskell, you have to be more consistent and precise. For example, in everyday life, we'd say "add five to three", but in Math and Haskell, we'd write `5 + 3`

.

It's good to realise there are usually many ways to look at something. For example, if we look at a toggle switch, and it’s marked “off”, does that mean it’s currently off, or that pressing it will “action” the off functionality? (ie turn it off). There is no one true right answer, so it’s good to be aware there are many ways to express the same thing that can often appear as complete opposites to each other.

Getting back to our machine, the moment we plug our `53 :: Int`

into the box, the type of the box changes from `Int -> Int`

to just `Int`

. We can then plug that whole expression `(plus5 53)`

into any other function box that takes an `Int`

as an argument. We may have to use brackets, though, in Haskell.

```
-- apply plus5 to 53:
plus5 53
-- apply plus5 to
-- the application of plus5 to 6
plus5 (plus5 6)
```

What if we wanted to plug the expression `plus5 53`

, into the function `plus5`

again? Well, we could do that like this: `plus5 (plus5 53)`

, and the result would be `63`

:

We can clearly see that the “output” of the first box as 58 can be plugged into the “input” of the second box. (Don’t get confused, this is not an `IO`

action! We’re not talking about actually outputting these numbers on the screen or anything, just plugging values into functions as a metaphor).

So, let’s move on and read a definition for this `plus5`

function. We already know what it does:

```
plus5 :: Int -> Int
plus5 x = x + 5
```

This is the type declaration and definition for a function that takes one argument of type `Int`

. We’re naming that argument `x`

here in this definition (that’s why the `x`

appears on the left of the `=`

sign). We could have named it almost anything we liked. To “use” this function, you supply `plus5`

with an `Int`

value by placing it to the right of it like this: `plus5 7`

.

The definition uses something special we haven’t seen yet called an **operator**. Here it's an **infix** function called `(+)`

that is named as the `+`

symbol, and it takes two numeric arguments, one on either side! A function is called an **infix** function when it appears between its arguments. Normal functions are called **prefix** because they are placed before their argument(s). Functions that are named as symbols like `(+)`

here are called **operators**, and they almost always only ever take exactly two arguments, and are usually infix, like `(+)`

. You'll also notice when we talk about them, we put parentheses around them. In Haskell this is how they're referred to outside of when you're using them in a function application.

Let’s look at another program that does almost the same thing. Notice we’re using a different variable name here (we called it number), rather than `x`

.

```
plus6 :: Int -> Int
plus6 number = number + 6
```

Now we’ll present another way to write this. If you have an infix operator such as `(+)`

, and you want to use it as a prefix function, you can just wrap it in parentheses. This function works exactly the same as `plus6`

:

```
plus6' :: Int -> Int
plus6' number = (+) number 6
```

Next we’ll present **another** identical function, but using what’s called a **section**. A section is a partially applied operator. That means it has one of its two arguments supplied, and that becomes a function. It always uses round brackets.

```
plus6'' :: Int -> Int
plus6'' number = (+6) number
```

See if you can guess the type of `(+6)`

right now. First, you might want to think about the type of the `(+)`

operator. It takes two numeric arguments, and returns one numeric argument. So, if one of its arguments are supplied, it will become a function of only one argument. Then, we apply this function to the number variable to get our result.

So, you can think of the type of the function `(+6)`

as taking a single number, then returning a number.

It doesn't matter which side you put the value on with the operator `(+)`

, because `(+)`

takes two identical arguments, and is an operation that works the same no matter the order. In math, this property is called the **commutative property**.

The word commute can be broken into **com-**, which means altogether, and **mut-** which means to change. Commutativity means the ability to interchange, so we can see that we can interchange the numbers between either side of `(+)`

, and it makes no difference.

Here are four functions that are identical in result:

```
sevenPlus :: Int -> Int
sevenPlus number = (7+) number
sevenPlus' :: Int -> Int
sevenPlus' = (7+)
plusSeven :: Int -> Int
plusSeven number = (+7) number
plusSeven' :: Int -> Int
plusSeven' = (+7)
```

Your homework is to get familiar with more definitions, and seeing how function arguments are used in function bodies. Don’t get too worried or confused by the many tricky weird looking things you’ll see as you look at other code.

We’ll show you some code below. You should also do an internet search for ”haskell defining functions”, go through the first 10 or so returned pages and quickly scan through them for value and function definitions. Remember there are two ways to define functions: either with the lambda syntax like `sevenPlus = \number -> (7+) number`

or with the “normal” syntax like `sevenPlus number = (7+) number`

. Your aim here is simply to recognise where the definitions are.

Here are the examples. Remember, don’t get caught on what you **don’t** know, just look for what you **do** know. Remember, you’re just looking for the definitions, especially the function definitions:

```
squaredNum :: Integer -> Integer
squaredNum x = x ^ 2
lengthNum :: Show a => a -> Int
lengthNum n = length $ show n
bool1, bool2 :: Bool
bool1 = True
bool2 = False
notBool :: Bool -> Bool
notBool b = if b == bool1 then bool2 else bool1
veryNotBool :: Bool -> Bool
veryNotBool = \aBool -> notBool aBool
sumFrom1To :: Integral a => a -> a
sumFrom1To 0 = 0
sumFrom1To n = n + sumFrom1To (n - 1)
isEven :: Integral a => a -> Bool
isEven n = n `mod` 2 == 0
```

If you’ve enjoyed reading this, please consider purchasing a copy at Leanpub today

Please follow us, and check out our videos Follow @HappyLearnTutes

Also, *Volume 2* is now in beta and being written! Show your support and register your interest at its Leanpub site.

Main Table of Contents

Previous chapter: 5. Function Magic

6. Sockets & Plugs

... 6.1. Reusability

... 6.2. Functions are Values

... 6.3. Plugging Values into Functions

... 6.4. Defining Functions

... 6.5. Operator Sections

... 6.6. What is commutivity?

... 6.7. Homework

Next chapter: 7. Output Other Things