Please Buy now at Leanpub

Written and illustrated by GetContented.

Published on 2016-06-05.

Previous chapter: 6. Sockets & Plugs

7. Output Other Things

... 7.1. Integer or Int?

... 7.2. Type Variables

... 7.3. Type Variables can be named anything

... 7.4. Typeclasses

... 7.5. The Show Typeclass

... 7.6. Parentheses and Precedence

... 7.7. The print Function

... 7.8. Homework

Next chapter: 8. Make Decisions

We’ve seen `putStrLn`

. It lets us output any `String`

on the screen.

What if we want to print out a number instead of a `String`

?

We have the following definition for an expression that is adding two numbers, and we want to print the resulting value out in a program.

```
number :: Integer
number = 100390 + 29389
```

(`Integer`

, by the way, is the type of **unbounded whole numbers** in Haskell. Unbounded means they have no upper or lower limit (or bounds). In contrast, the `maxBound`

of `Int`

that this document is being prepared on now is 9223372036854775807.)

So, we know that the `putStrLn :: String -> IO ()`

function takes a `String`

, and leaves us with an `IO ()`

value.

We don’t have a `String`

, though, we have an `Integer`

value. How can we match these up so we can print out our number on the screen?

In order to answer that, let’s first look at the type of the `(+)`

function. We know from experience that it takes a number and another number and returns their sum as a number, but the actual type isn't something we’ve seen, and includes some special new stuff for us. Let’s look:

```
(+) :: Num a => a -> a -> a
```

Ok, breathe. Let’s first look at the right side: `a -> a -> a`

. Why all the `a`

’s?

Well, we know from all the `(->)`

’s that this means it’s a function that takes **two** values of type “`a`

”, and returns a third “`a`

”. What is “`a`

”, though? It’s what’s called a **type variable**. That means it can be any type. If it starts with a lowercase letter, it’s a type variable. If it starts with a capital, it’s an actual type, or a typeclass, which we'll explain soon (Num is a typeclass in `Num a => a`

).

One important point about **type variables** is that while they can be any type at all, all the “`a`

”s must still be the same type as each other when using the function! So if we used an `Integer`

value as our first argument, so saying that the first type `a`

was `Integer`

in `(+)`

, then we would need to use an `Integer`

as our second argument, too:

```
-- both types must be the same,
-- so this will be fine:
goodNumber = (3 :: Integer) + (5 :: Integer)
-- this would cause a type error
willNotWork = (3 :: Int) + (5 :: Integer)
```

If we don't specify the type of our numbers, Haskell's **type inference** works it out for us, which saves a lot of time and hassle.

Ok, so here is another way to write the `(+)`

function, which shows you that variables don’t necessarily have to be named `a`

:

```
-- it's a lot smaller to write
-- 'a' than 'theNumber'
(+) :: Num theNumber =>
theNumber ->
theNumber ->
theNumber
```

Now we have to think about the “`Num a =>`

” part. That can be read as “`a`

is constrained to types which are instances of the `Num`

typeclass”. This mouthful means that the `(+)`

function can take two arguments of any type at all (here we’re naming them `a`

), as long as that type (again, here called `a`

) is an instance of a typeclass called `Num`

. Luckily for us, all numbers are!

A **typeclass** is not a concrete type like `Integer`

, `Int`

or `String`

. It’s a way of tagging **many** types (a “class” of them, if you like) so that we can have functions or values that work with many similar types that do similar things, but that are actually different. Let's take a look:

```
-- a small int 5:
intFive = 5 :: Int
-- a "floating-point" value of 10.3
floatTenPointThree = 10.3 :: Float
-- add them together with (+). This will not work...
-- because both types are concretized (or specialized)
errorResult = intFive + floatTenPointThree
-- add them together with (+). This will work
result = (fromIntegral intFive) + floatTenPointThree
-- the result is 15.3
```

Here we’re using `fromIntegral`

to build an “unspecialised” `Num a => a`

version of the `Int`

value of `intFive`

so we can subsequently add it to `floatTenPointThree`

. The value `5 :: Int`

is not of type `Float`

, so the types won’t match unless we do this. However, if either of the values are of type `Num a => a`

, then `(+)`

will typecheck because it can match both types together (by concretizing the `Num a => a`

type to `Float`

).

The `Float`

, `Int`

, and `Integer`

types are all instances of the `Num`

typeclass. There are many numeric types in Haskell such as these. To be able to do arithmetic functions on different numeric typed values, they are tagged as `Num`

which allows us to define each of the simple arithmetic functions for each type differently, but use them all with the same name and interchange values.

This “tagging” is called making a type an instance of a typeclass. When a programmer does this, they provide a definition against the particular type, for the functions that the typeclass requires.

So we can see that `(+)`

can add a `Float`

or an `Integer`

to a `Num a => a`

without a problem. The `Num`

typeclass is, in this way, like a kind of contract that programmers of a type can decide to kind of "subscribe to" which gives them the ability to write implementations of the functions that the `Num`

typeclass provides. In turn, the typeclass system gives that type the ability to work with all the other types that are instances of that typeclass.

So the `Num`

typeclass means there actually isn’t only one definition for the functions for addition: `(+)`

, subtraction: `(-)`

, multiplication: `(*)`

, negation: `negate`

, etc but rather that each type — that is, each instance of `Num`

— has **its own** definition for each of these functions.

What does all of this have to do with printing our number on the screen? Remeber, that problem we started the chapter with?

Well, there’s a typeclass called `Show`

(with a big S), and this provides a single function: `show`

(with a small s), that can take any instance of `Show`

, and makes a `String`

version of it. Let’s look at the type of the `show`

function:

```
-- takes a "showable" thing
-- and returns a String
show :: Show a => a -> String
```

We see that show is a function which takes a single argument of any type (the “`a`

” type variable above) constrained to the `Show`

typeclass, and returns a `String`

. That single argument is anything that has an instance of `Show`

defined for it. We know this because of the `Show a =>`

constraint.

Printing things to the screen is such a common thing to do that many types have an instance of `Show`

already, including of course, `Integer`

and `Int`

, so getting back to the first program of this chapter, we can just apply `show`

to our `Integer`

and then pass it to `putStrLn`

. Let’s see how:

```
number :: Integer
number = 100390 + 29389
main :: IO ()
main = putStrLn (show number)
```

Parentheses are needed on `show number`

because `putStrLn`

only takes **one** argument, and the function application **precedence** rules mean that taking them off would give it **two**. Precedence is a fancy-pants word that simply means “which things come before or after which other things”. If we left off the parentheses, we would have this: `putStrLn show number`

, which Haskell would see as “apply `putStrLn`

to the value `show`

, and then apply that to the value `number`

”. However, `putStrLn`

takes only `String`

values, and `show`

is a function, so that would **definitely** be a type error.

We have one last trick up our sleeves to show you (pardon the pun). It’s the `print`

function. This is very similar to `putStrLn :: String -> IO ()`

, but rather than taking a String, it can take a value whose type is any instance of `Show`

! Let’s see a version of our program that uses `print :: Show a => a -> IO ()`

rather than `putStrLn`

:

```
number :: Integer
number = 100390 + 29389
main :: IO ()
main = print number
```

See if you can work out what the following program does.

```
number1 :: Num a => a
number1 = 1 + 5 + 7 + 3 + 2
number2 :: Num a => a
number2 = number1 * number1
main :: IO ()
main = print number2
```

**Hint:** don’t get caught up by the types of the values. This **will** probably be confusing, and **should** confuse you at least a little bit. We’ll explain what’s going on later, however, the important thing is just see if you can work out what the program will **do** when you run it.

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: 6. Sockets & Plugs

7. Output Other Things

... 7.1. Integer or Int?

... 7.2. Type Variables

... 7.3. Type Variables can be named anything

... 7.4. Typeclasses

... 7.5. The Show Typeclass

... 7.6. Parentheses and Precedence

... 7.7. The print Function

... 7.8. Homework

Next chapter: 8. Make Decisions