While we’ve talked a little about types already, our interactions with *ghci* have so far been free of much
type-related thinking. We haven’t told *ghci* what types we’ve been using, and it’s
mostly been willing to accept our input.

Haskell requires type names to start with an uppercase letter, and variable names must start with a lowercase letter. Bear this in mind as you read on; it makes it much easier to follow the names.

The first thing we can do to start
exploring the world of types is to get *ghci* to tell us more about what it’s doing.
*ghci* has a command, *:set*, that lets us change a few of its default behaviors. We can tell
it to print more type information as follows:

`ghci>`

`:set +t`

`ghci>`

'c' it :: Char`'c'`

`ghci>`

"foo" it :: [Char]`"foo"`

What the `+t`

does is tell
*ghci* to print the type of an
expression after the expression. That cryptic `it`

in the output can be very
useful: it’s actually the name of a special variable, in which *ghci* stores the result of the last expression
we evaluated. (This isn’t a Haskell language feature; it’s specific to
*ghci* alone.) Let’s break down the
meaning of the last line of *ghci*
output:

Here are a few more of Haskell’s names for types, from expressions of the sort that we’ve already seen:

`ghci>`

40536215597144386832065866109016673800875222251012083746192454448001 it :: Integer`7 ^ 80`

Haskell’s integer type is named Integer. The size of an Integer value is bounded only by your system’s memory capacity.

Rational numbers don’t look quite the same as integers.
To construct a rational number, we use the `(%)`

operator. The numerator is on the left, the denominator on the
right:

`ghci>`

`:m +Data.Ratio`

`ghci>`

11%29 it :: Ratio Integer`11 % 29`

For convenience, *ghci* lets us abbreviate many commands, so we
can write *:m* instead of
*:module* to load a module.

Notice there are *two* words on the
righthand side of the `::`

in the preceding code. We can read
this as a “Ratio of Integer.” We might guess that a Ratio
must have values of type Integer as both numerator and
denominator. Sure enough, if we try to construct a Ratio
where the numerator and denominator are of different types or of the
same nonintegral type, *ghci*
complains:

`ghci>`

<interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from a use of `%' at <interactive>:1:0-7 `Fractional t' arising from the literal `3.14' at <interactive>:1:0-3 Probable fix: add a type signature that fixes these type variable(s)`3.14 % 8`

`ghci>`

<interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from a use of `%' at <interactive>:1:0-8 `Fractional t' arising from the literal `3.4' at <interactive>:1:6-8 Probable fix: add a type signature that fixes these type variable(s)`1.2 % 3.4`

Although it is initially useful to have
** :set +t** giving us type
information for every expression we enter, this is a facility we will
quickly outgrow. After a while, we will often know what type we expect
an expression to have. We can turn off the extra type information at any time, using the

`ghci>`

`:unset +t`

`ghci>`

2`2`

Even with this facility turned off, we can
still get that type information easily when we need it, using another
*ghci* command:

`ghci>`

'a' :: Char`:type 'a'`

`ghci>`

"foo"`"foo"`

`ghci>`

it :: [Char]`:type it`

The *:type* command will print type information for any expression we give it
(including `it`

, as we see here). It won’t actually
evaluate the expression; it checks only its type and prints that.

Why are the types reported for these two expressions different?

`ghci>`

5`3 + 2`

`ghci>`

it :: Integer`:type it`

`ghci>`

3 + 2 :: (Num t) => t`:type 3 + 2`

Haskell has several numeric types. For
example, a literal number such as `1`

could, depending on the context in which it appears, be an integer or a
floating-point value. When we force *ghci* to evaluate the expression ```
3 +
2
```

, it has to choose a type so that it can print the value, and it
defaults to Integer. In the second case, we ask *ghci* to print the type of the expression
without actually evaluating it, so it does not have to be so specific.
It answers, in effect, “its type is numeric.” We will see more of this
style of type annotation in Chapter 6.

Start Free Trial

No credit card required