Inspecting Types and Errors

Introduction

Welcome to the fourth unit of our course! So far in our journey, we have written simple programs, defined pure functions, and learned how to explicitly assign types like Int and Double to our values.

As you have likely noticed, Haskell is very strict about types. It will not allow you to mix different types together unless you explicitly tell it how to do so. While this strictness is an incredible feature that prevents many common programming bugs, it can sometimes be frustrating when your code refuses to run. In this lesson, we will learn how to act as a type detective. You will learn how to investigate types, read the helpful error messages the compiler gives us, and fix common type mismatches.

Inspecting Types with the :t Command

When working with Haskell, we have access to a tool called GHCi. This is Haskell's interactive environment, and it is a fantastic place to experiment with code. On the CodeSignal platform, you can open a terminal and type ghci to start it. You will then see the ghci> prompt, where you can type expressions and commands. When you are finished exploring, type :quit (or its shortcut :q) to leave the session and return to your normal terminal.

One of the most powerful features of GHCi is the :t command. This command allows you to ask Haskell, "What type is this value?"

Let us look at a simple example. If you type :t followed by a true or false value in GHCi, here is what you will see:

Haskell
ghci> :t False
False :: Bool

Haskell responds by showing us the value, followed by ::, and then the type. As a reminder from earlier lessons, the :: symbol translates to "has the type of." So, Haskell is telling us that False has the type of Bool (a boolean).

We can do the same thing with text:

Haskell
ghci> :t "Hello"
"Hello" :: String

Here, Haskell confirms that "Hello" is a String. Whenever you are unsure about what type of data you are working with, the :t command is your best friend.

Reading Type Constraints: Num a =>

Things get a little more interesting when we ask GHCi about a simple number. Let us see what happens when we use the :t command on the number 5:

Haskell
ghci> :t 5
5 :: Num a => a

This output looks a bit different from Bool or String. You might be wondering why it does not just say Int.

In Haskell, the arrow symbol => is used to define a rule or a constraint. When you see Num a => a, you can read it in plain English as: "For any type a that acts like a number, this value can be that type a."

Because the number 5 does not have a decimal, it could be used as a whole number (Int), but it could also safely be treated as a decimal number (Double). Haskell is letting us know that the number 5 is flexible.

For now, you do not need to worry about writing these => constraints yourself. The goal here is simply to build your intuition so you can read and understand what Haskell is telling you when you inspect values.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal