Haskell Course - Lesson 2 - Haskell Type system

Types are attributes that constraint the values a piece of code can have. For example, if you indicate that some data is a number, that data could have any of these values:

  • 4
  • 32
  • 9999695939294
  • 0.5

But, if you try to add a character in there, like this: 6A3 (instead of 63), the compiler/

will yell at you: "That's not a number, you imbecile!" (you got a sassy one, my condolences).

What your compiler/interpreter did just there is called "type checking." Some languages have more strongly enforced type checking, some less.

First, we'll see an overview of the concepts, and then, we'll talk specifically about Haskell.

Type checking

Type checking is the process of verifying and enforcing the constraints of types.

What does this mean? It means that each type has its own constraints (E.g., you can't do math with letters. Unless... πŸ€” No, no, you can't), and this process checks that those constraints are respected.

Why would you do this? To avoid preventable mistakes. If further along in your program, you want to add up some numbers and one of them has a letter, the program wouldn't know what to do, and it would

on you. Those are preventable mistakes
, and the compiler/interpreter helps you avoid them.

Usually, this is done automatically. But not all languages do this the same way. There are two main distinctions regarding as to WHEN the types are checked.

Dynamically typed languages

Dynamically typed languages check the types at run-time. Run-time is the very last thing that you do with a program. It's the stage when you run your program to test it or use it.

Meaning that you won't know if your types are correct until you actually use the program. And if your types are wrong, your program will crash.

Common examples of dynamically-typed languages include JavaScript, Python, Objective-C, and PHP.

The counterpart of dynamically typed languages are statically typed languages.

Statically typed languages

Statically typed languages check the types at compile-time. Meaning that you'll know if your types are wrong as soon as you compile your program (and some IDEs will show you the exact place where the error occurs). Which leads to a safer and more optimized code.

Common examples of statically-typed languages include Java, C, and C++.

It sounds like all programming languages should be statically typed, but it's not that simple. Both statically and dynamically typed languages have their pros and cons. In some cases, you want to use dynamically typed languages (E.g., quick prototyping), and in others, you want to use statically typed languages (E.g., writing robust and optimized programs).

That's our overview of the general concepts. Now let's see how Haskell fits into all of this.

Haskell type system

Haskell is statically typed. And, in Haskell, Everything has a type.

And not only that. In some programming languages, each time you write a piece of code, you have to indicate the types. But not in Haskell! Haskell is smarter than other languages πŸ€“ because it has type inference.

Type inference allows Haskell to infer the types on its own. If you write something like 3 + 4, Haskell will know that the result of that expression is a number, and it will treat like it without the need for you to specify anything.

That allows the compiler to comprehend and reason quite a lot about your program. Providing you with a pretty effective bug-catching assistant. πŸ’ͺ (You still have to write sensible code though, you can't expect the compiler to do all the work. 😜)

But what if the code is ambiguous or can have more than one type? (we'll see examples in future lessons). Haskell will try to infer the type, and if it can't, it will β€” you guessed it β€” yell at you to specify it. πŸ˜‚

But how do you know/set the type? To see and specify the type of a piece of code, we use the :: operator.

The :: operator

An operator is a symbol to perform specific mathematical, relational, or logical operations. In this case, the :: operator is used to show or assign types.

When you read code with that operator, you can read it as "has type of." Here's how it looks:

🐬 :: Animal -- This reads as: 🐬 has type of Animal

πŸ₯ :: Food   -- This reads as: πŸ₯ has type of Food

Obviously, those are not standard Haskell types. We'll explore the properties of the most common Haskell types and the use of the :: operator in practice in the following lectures.

And that's it for today! πŸ™ƒ Make sure to do the homework and solidify today's concepts! πŸ€“


  1. Answer these questions in your head and open them to check your answer (repeat every few minutes until you get all of them right):

Attributes that constraint the values a piece of code can have

The process of verifying and enforcing the constraints of types.

Dynamically typed languages check the types at run-time, and statically typed languages, check the types at compile-time.

Haskell will try to infer the type. And if it can't, it'll ask me to specify it.

USD :: Currency 
  1. Search the difference between strongly typed languages and weakly typed languages.

In the next lesson, we'll learn about Numbers in Haskell! βž•βž–βž—βœ–οΈ See you there!! πŸ˜„

PD: If you find this course valuable, please share it so more people can learn! πŸ˜„