Haskell Course - Lesson 4 - Characters, Lists, and Strings
In the last lesson, we got familiar with numeric types. In this lesson, we'll learn about common text types. After this lesson, you'll be able to understand, use, and manipulate text in Haskell easily. Are you ready? Let's go! 💪🔥
Char
Char
is the type we use to represent a
Unicode character
The Unicode standard (Unicode) is a set of rules that enforce a way of handling and expressing text. It's needed because computers think in numbers (ones and zeroes), and we have to collectively decide which numbers represent which characters.
It's actually a little more complicated (see: Character encoding. But for our purpose, we just want to know that we can use almost any symbol that we'll ever need by using Unicode characters. Letters, numbers, and more than 140k+ symbols.
We write values of type Char
(Unicode characters) between single quotes. Like this:
'a'
'5'
Note that if you write a number surrounded by single quotes (like in the last expression), Haskell won't treat it like a number. It will treat it like any other character. So, you can't do math with '7'
(with quotes), but you can with 7
(without quotes).
Important: You can only write a single character at a time! This: will make your compiler yell at you. And you don't want to start the relationship with your compiler like that. 😅'hi'
This one is easy, so we won't waste more time on it.
I know that you want to write more than one character at a time. I get it. You don't want to sound like a freezing caveman. 🥶 But before that, we have to learn about lists.
Lists
Lists are homogeneous
Data structure
A data structure is a data organization, management, and storage format that enables efficient access and modification. Is a collection of data values, the relationships among them, and the functions or operations that can be applied to the data.
We represent lists by starting with [
, writing the elements separated by ,
, and ending with ]
. This is an example of a list with three numbers:
[42,404,666]
And this is an example of a list with 5 characters:
['h','e','l','l','o']
In this case, the first element of the list is the Char
of value 'h'
, the second element is the Char
of value 'e'
, and so on.
List type
Important: Lists are homogeneous! That means that you can't have a list with elements of different types! [1,'2',3]
will give your compiler a serious migraine! '2'
is a character, not a number! You can't have both Int
and Char
types! You have to choose one or the other!
The type of a list is expressed as the type of the elements that it contains surrounded by squared brackets. A list of type [Int]
contains numbers of type Int
. A list of type [Char]
contains elements of type Char
.
You can specify the type of a list the same way you can specify the type of an element. Using the ::
operator:
-- Option 1:
[1,2,3] :: [Float] -- Will give you a list of Floats
-- Option 2:
[1 :: Float,2,3] -- Will give you a list of Floats
In option 1, we indicate that all the numbers are Float
.
In option 2, we indicate that only the first number is of type Float
. But, because Haskell can infer the types (remember lesson 2), it knows that all the elements are of type Float
. How can it tell? If the first element is a Float
and all the elements of a list are of the same type, then all elements are Float
s.
Keep in mind that you can't specify a type that doesn't fit with the elements. If you have characters as elements and specify a numeric type, you'll get an error.
Usually, it's not needed to specify the type at all. Just let Haskell infer its way through and keep on coding.
We'll see more about lists, but before that, fire up your GHCi, copy and paste the list with 5 characters from before (['h','e','l','l','o']
), and hit enter 👀.
That's a String
! 😄
Strings
Strings represent lists of characters. You can use the String
type to write messages, alphanumeric values, symbols, etc. Unlike Char
s, String
s are surrounded with double-quotes like this:
"Hellooooooo!"
"My phone number is 354XXXXXXXX"
"My bank's account password is: NeverGonnaGiveYouUp_NeverGonnaLetYouDown"
Waaaaaaait a minute! You just said that a list of characters is of type
— Weirdly angry student? 😂[Char]
. And now you're telling me thatString
represents a list of characters? Which is it, you trickster?
It's both! 😁 Because String
and [Char]
are the same type! More specifically, String
is
Syntactic sugar
Syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.
[Char]
So, you can use them interchangeably.What you can't use interchangeably in Haskell are single and double-quotes. String
s (written in double-quotes) are lists of Char
(written using single quotes). These are not the same!:
"A" -- String or [Char]
'A' -- Char
The first one is the same as ['A']
. And a list that contains the 'A'
element is not the same as just the 'A'
element!
As you can see, we can write a String
with a single character (e.g, "p"
), but you can't write a Char
with multiple characters (e.g. ).'hi'
Courtesy of System32Comics
Now that we're familiar with lists and Strings, let's have some fun!
Fun with Lists
Accessing lists elements
You can access a specific element inside a list by using its index. Every element has an index determined by its position inside the list — starting at 0
(zero).
So, in this case:
['a','b','c']
The index of 'a'
is 0
, the index of 'b'
is 1
, and the index of 'c'
is 2
.
Lists indices start at 0
in almost all programming languages.
Now, how do we access a specific element using the index? By using the !!
operator. The !!
operator has to be written like this (a list to its left and the index of the element we want to its right):
['a','b','c'] !! 1 -- This will give us 'b'
[12,13,16,18] !! 3 -- This will give us 18
Think about it, and then use GHCi to check your answer. You don't need me to tell you (...kids grow up so fast 😢...).
An error! Because there's no element of index 3
. The list ends at index 2
of value 'f'
! If you try in GHCi, the compiler will tell you that the index is too large.
Accessing elements sounds wonderful, but what if you have a bunch of lists? Do you have to access them one by one? Well, you could. But you could also concatenate them first! 👀
Concatenation of lists
A common operation with lists is
Concatenation
Concatenation is the operation of joining two things (usually strings or lists) end-to-end.
We concatenate in Haskell by using the ++
operator. Even though we know that this operator is two +
one after the other, Haskell doesn't see it that way. For Haskell, ++
is a single thing! It's an operator that concatenates two lists (and only two lists). Nothing to do with +
.
We can use the operator like this (try it out in GHCi):
[1,2,3] ++ [4,5,6] -- [1,2,3,4,5,6]
Exactly! Strings are lists as well, so we can do all the things that we can do with lists.
We can also use the operator as much as needed:
"Hello" ++ " " ++ "World!"
This way, you can create complex messages by combining more simple ones.
Ok, that's it for now. I have to leave something for next week! 😂
We can do many (many many many) more cool things with lists. That's why lists will have their own lesson (maybe two lessons? 🤔, we'll see). For now, make sure to complete this week's homework! 😄
Homework
Solutions for lesson's 3 homework
- How many ºC is
100
ºF? ➡️(100 - 32) *5/9
= 37.77ºC - How many ºC is
32
ºF? ➡️(32 - 32) *5/9
= 0ºC - How many ºC is
212
ºF? ➡️(212 - 32) *5/9
= 100ºC
Predict the result of the expressions (use GHCi if needed)
Error! You can't concatenate a lists of different type!
It's 2
! The expression to obtain the result is:
([3,7,5,1] ++ [0,5,1,2,9,8,4]) !! 7
Error! You can't concatenate a string with a single character!
By indicating that they are of type Double
:
[1,2,3] :: [Double]
or
[1 :: Double ,2,3]
We're done for today! 👏 Next lesson, we'll learn about Booleans and Tuples! Those will be our last types before learning about functions!! 🤩 See you there!!
PD: If you find this course valuable, please share it so more people can learn! 😄