0% found this document useful (0 votes)
40 views145 pages

Haskell The Ultimate Beginner S Guide To Learn Haskell Programming Step by Step 1st Edition Claudia Alves Instant Download

The document is a guide for beginners to learn Haskell programming, authored by Claudia Alves. It covers key concepts of Haskell, including its functional programming nature, strong static typing, lazy evaluation, and practical applications in various industries. The guide also provides instructions on setting up a Haskell environment and using the Glasgow Haskell Compiler (GHC) for interactive coding.

Uploaded by

sqsludky351
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views145 pages

Haskell The Ultimate Beginner S Guide To Learn Haskell Programming Step by Step 1st Edition Claudia Alves Instant Download

The document is a guide for beginners to learn Haskell programming, authored by Claudia Alves. It covers key concepts of Haskell, including its functional programming nature, strong static typing, lazy evaluation, and practical applications in various industries. The guide also provides instructions on setting up a Haskell environment and using the Glasgow Haskell Compiler (GHC) for interactive coding.

Uploaded by

sqsludky351
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 145

Haskell The Ultimate Beginner s Guide to Learn

Haskell Programming Step by Step 1st Edition


Claudia Alves pdf download
https://textbookfull.com/product/haskell-the-ultimate-beginner-s-guide-to-learn-haskell-programming-
step-by-step-1st-edition-claudia-alves/

★★★★★ 4.8/5.0 (41 reviews) ✓ 196 downloads ■ TOP RATED


"Great resource, downloaded instantly. Thank you!" - Lisa K.

DOWNLOAD EBOOK
Haskell The Ultimate Beginner s Guide to Learn Haskell
Programming Step by Step 1st Edition Claudia Alves pdf
download

TEXTBOOK EBOOK TEXTBOOK FULL

Available Formats

■ PDF eBook Study Guide TextBook

EXCLUSIVE 2025 EDUCATIONAL COLLECTION - LIMITED TIME

INSTANT DOWNLOAD VIEW LIBRARY


Collection Highlights

Lua Programming The Ultimate Beginner s Guide to Learn Lua


Step by Step 3rd Edition Claudia Alves

The Ultimate Beginner s Guide to Learn kotlin Programming


Step by Step 2020 2nd Edition Moaml Mohmmed

Go programming language The Ultimate Beginner s Guide to


Learn Go Programming Step by Step 3rd Edition John Bach

Python Programming A Step By Step Guide From Beginner To


Advance Second Edition Eddison
Scala Programming A comprehensive beginner s guide to
Scala 2nd Edition Claudia Alves

Learn to Program with Python 3: A Step-by-Step Guide to


Programming Irv Kalb

Learn to Program with Python 3: A Step-by-Step Guide to


Programming, 2nd Edition Irv Kalb

ANSI C Programming Learn ANSI C Step by Step 1st Edition


Yashavant Kanetkar

Beginner Gardening Step by Step A Visual Guide to Yard and


Garden Basics 1st Edition Emma Tennant
Haskell
The Ultimate Beginner's Guide to Learn Haskell Programming Step by Step

1st edition
2020

By Claudia Alves
"Programming isn't about what you know; it's
about what you can figure out.” - Chris Pine
memlnc

INTRODUCTION
WHAT MAKES HASKELL SPECIAL?
HOW IS HASKELL USED?
WHAT DO YOU NEED TO START
STARTING
READY, SET, GO!
THE FIRST SMALL FUNCTIONS
AN INTRODUCTION TO THE LISTS
TEXAS RANGES
I'M AN INTENSIONAL LIST
TUPLES
CHAPTER I
TYPES AND TYPE CLASSES
BELIEVE IN THE TYPE
TYPE VARIABLES
TYPE CLASSES STEP BY STEP (1ST PART)
CHAPTER II
THE SYNTAX OF FUNCTIONS
PATTERN ADJUSTMENT
GUARDIANS, GUARDIANS!
WHERE?
LET IT BE
CASE EXPRESSIONS
CHAPTER III
RECURSION
HELLO RECURSION!
THE IMPRESSIVE MAXIMUM
A FEW MORE RECURSIVE FUNCTIONS
QUICKSORT!
THINKING RECURSIVELY
CHAPTER IV
HIGHER ORDER FUNCTIONS
CURRIFIED FUNCTIONS
HIGHER ORDER IN YOUR ORDER
ASSOCIATIONS AND FILTERS
LAMBDAS
FOLDS AND ORIGAMI
APPLICATION OF FUNCTIONS WITH $
COMPOSITION OF FUNCTIONS
CHAPTER V
MODULES
LOADING MODULES
DATA.LIST
DATA.CHAR
DATA.MAP
DATA.SET
CREATING OUR OWN MODULES
CHAPTER VI
CREATING OUR OWN TYPES AND TYPE
CLASSES
INTRODUCTION TO ALGEBRAIC DATA TYPES
REGISTRATION SYNTAX
TYPE PARAMETERS
DERIVED INSTANCES
TYPE SYNONYMS
RECURSIVE DATA STRUCTURES
TYPE CLASSES STEP BY STEP (2ND PART)
THE YES-NO TYPE CLASS
THE FUNCTOR TYPE CLASS
FAMILIES AND MARTIAL ARTS
CHAPTER VII
INPUT AND OUTPUT
HELLO WORLD!
FILES AND DATA STREAMS
COMMAND LINE PARAMETERS
RANDOMNESS
BYTE STRINGS
EXCEPTIONS
Introduction
A balance of flexible and inflexible qualities make Haskell a fascinating
programming language to learn and use.

First, the Haskell programming language is not named after Eddie Haskell,
the sneaky double-dealing neighbor kid in the ancient TV sitcom, Leave It To
Beaver.

Haskell is named after Haskell Brooks Curry, an American mathematician


and logician. If you don't know, logicians create models to describe and
define human reasoning, for example, problems in mathematics, computer
science, and philosophy. Haskell’s main work was in combinatory logic, a
notation designed to eliminate the need for variables in mathematical logic.
Combinatory logic captures many key features of computation and, as a
result, is useful in computer science. Haskell has three programming
languages named after him: Haskell, Brooks, and Curry.

Haskell the language is built around functions, useful blocks of code that do
specific tasks. They are called and used only when needed.

Another interesting feature of functional languages like Haskell: functions are


treated as values like integers (numbers) and strings. You can add a function
to another function the way you can add an integer to an integer, 1 + 1 or 35
+ 53. Perhaps the best way to describe this quality is a spreadsheet: in a cell
in the spreadsheet, you can add numbers as well as a combination of
functions to work on numbers. For example, you might specify each number
in cells 1-10 be added up as a sum. In Excel, at least, you also can use
SUMIF to look for a pattern in cells 1-10 and, if the pattern is found, perform
an action on any cells with the pattern.
What Makes Haskell Special?
Technically, Haskell is a general-purpose functional programming language
with non-strict semantics and strong static typing. The primary control
construct is the function. (Say that fast ten times!) Here's what it means:

- Every language has a strategy to evaluate when to process the input


arguments used in a call to a function. The simplest strategy is to evaluate the
input arguments passed then run the function with the arguments. Non-strict
semantics means the input arguments are not evaluated unless the arguments
passed into the function are used to evaluate what is in the body of the
function.

- Programming languages have rules to assign properties — called a type


— to the components of the language: variables, functions, expressions, and
modules. A type is a general description of possible values the variable,
function, expression, or module can store. Typing helps minimize bugs, for
example, when a calculation uses a string ("house” or "cat”) instead of a
number (2 or 3). Strong static typing evaluates the code before runtime, when
the code is static and possibly as code is written.

- The order in which statements, instructions and functions are evaluated


and executed determines the results of any piece of code. Control constructs
define the order of evaluation. Constructs use an initial keyword to flag the
type of control structure used. Initial keywords might be "if” or "do” or
"loop” while final keywords might be "end if” or "enddo” or "end loop”.
Instead of a final keyword, Haskell uses indentation level (tabs) or curly
brackets, or a mix, to indicate the end of a control structure.

Perhaps what makes Haskell special is how coders have to think when they
use the language. Functional programming languages work in very different
ways than imperative languages where the coder manages many low-level
details of what happens in their code and when. While it is true all languages
have things in common, it’s also true languages are mostly functional or
mostly imperative, the way people are mostly right handed or left handed.
Except functional programming languages require a different way of thinking
about software as you code.

Other features that make Haskell interesting:

- Strong data typing (evaluating properties of all inputs into a function)


is combined with polymorphism; a function to sort numbers also can be
used to sort strings of text. In some languages, you would have to code
two or more functions, one for each data type.

- Lazy evaluation (one of my favorite coding terms!) allows the result of


one function/task to be handed to another function/task on the same line
of code. For example, the command can search a file for all instances of a
string then pass the results to be printed to the computer screen.
Functions that can take other functions as arguments or return them as
results also are called higher order functions.

- No side effects. In other languages, code can affect the state of the
computer and application, for example, writing to a file. Haskell strictly
limits these side effects which, in turn, makes Haskell applications less
prone to errors.

- Haskell uses monads, a structure that works like an assembly line


where every stop on the line performs a different task. This allows
Haskell to separate side effects as a distinct activity apart from any
function, for example, logging any errors as a function performs tasks on
its data inputs.

Building from small bits of code, each bit tightly contained and testable.

How is Haskell Used?


As a functional programming language, Haskell has benefits like shorter
development time, cleaner code, and high reliability. The tight control of side
effects also eliminates many unforeseen interactions within a code base.
These features are especially of interest to companies who must build
software with high fault tolerances, for example, defense industries, finance,
telecommunications, and aerospace.

However, Haskell also is used in web startups where functional programming


might work better than imperative programming. Apparently Facebook,
Google, NVIDIA, and other companies use Haskell to build internal tools
used in their software development and IT environments. Even a lawn mower
manufacturer in Kansas uses Haskell to build and distribute their mowers.
And the New York Times recently used Haskell to build an image processing
tool for the 2013 New York Fashion week.

So what is Haskell?

Haskell is a purely functional programming language . In imperative


languages we obtain results by giving the computer a sequence of tasks that it
will then execute. While running them, you can change state. For example,
we set the variable to 5, perform some tasks, and then change the value of the
previous variable. These languages have flow control structures to carry out
certain actions several times ( for , while ...). With purely functional
programming we do not tell the computer what it has to do, but rather, we say
how things are. The factorial of a number is the product of all the numbers
from 1 to that number, the sum of a list of numbers is the first number plus
the sum of the rest of the list, etc. We express the form of the functions. Also
we can't set a variable to something and then set it to something else. If we
say that a is 5, then we cannot say that it is something else because we have
just said that it is 5. Are we liars? Thus, in purely functional languages, a
function has no side effects. The only thing a function can do is calculate and
return something as a result. At first this may seem like a limitation but in
reality it has some good consequences: if a function is called twice with the
same parameters, we will always get the same result. We call this referential
transparency and it not only allows the compiler to reason about the behavior
of a program, but it also allows us to easily deduce (and even demonstrate)
that a function is correct and thus be able to build more complex functions by
joining simple functions.

Haskell is lazy . That is, unless we tell you otherwise, Haskell will not
execute functions or calculate results until you are really forced to. This
works very well in conjunction with referential transparency and allows us to
view programs as a series of data transformations. It even allows us to do
cool things like infinite data structures. Let's say we have a list of immutable
numbers xs = [1,2,3,4,5,6,7,8] and a doubleMe function that multiplies each item
by 2 and returns a new list. If we wanted to multiply our list by 8 in an
imperative language if we did doubleMe (doubleMe (doubleMe (xs))) , the computer
would probably loop through the list, make a copy and return the value. Then
it would go through the list two more times and return the final value. In lazy
language, calling doubleMe with an unforced list to display the value ends up
with a program telling you "Sure, sure, then I'll do it!". But when you want to
see the result, the first doubleMe tells the second one that he wants the result,
now! The second says the same to the third and the latter reluctantly returns a
duplicate 1, which is a 2. The second receives it and returns a 4 to the first.
The first one sees the result and says that the first item in the list is an 8. In
this way, the computer only makes a journey through the list and only when
we need it. When we want to calculate something from initial data in lazy
language, we just have to take this data and transform and mold it until it
resembles the result we want.

Haskell is a statically typed language . When we compile a program, the


compiler knows which pieces of the code are integers, which are text strings,
etc. Thanks to this a lot of possible errors are caught at compile time. If we
try to add a number and a text string, the compiler will scold us. Haskell uses
a fantastic type system that has type inference. This means that we don't have
to explicitly tag each piece of code with a type because the type system can
intelligently deduce it . Type inference also allows our code to be more
general, if we have created a function that takes two numbers and adds them
together and we do not explicitly set their types, the function will accept any
pair of parameters that act as numbers.
Haskell is elegant and concise. It is because it uses high-level concepts.
Haskell programs are typically shorter than the imperative equivalents. And
short programs are easier to maintain than long ones, and they have fewer
errors.
Haskell was created by some very smart guys (all of them with their
respective doctorates). The project to create Haskell began in 1987 when a
committee of researchers agreed to design a revolutionary language. In 2003
the Haskell report was published, thus defining a stable version of the
language.

What do you need to start


A Haskell text editor and compiler. You probably already have your favorite
text editor installed so we're not going to waste your time on this. Right now,
Haskell's two main compilers are GHC (Glasgow Haskell Compiler) and
Hugs. For the purposes of this guide we will use GHC. I will not cover many
details of the installation. In Windows it is a matter of downloading the
installer, pressing "next" a few times and then restarting the computer. In
Debian-based Linux distributions it can be installed with apt-get or by
installing a deb package . In MacOS it is a matter of installing a dmg or using
macports . Whatever your platform, here is more information.
GHC takes a script from Haskell (they usually have the .hs extension ) and
compiles it, but it also has an interactive mode which allows us to interact
with these scripts. We can call the functions of the scripts that we have
loaded and the results will be shown immediately. It is much easier and faster
to learn instead of having to compile and run the programs over and over
again. Interactive mode is executed by typing ghci from your terminal. If we
have defined some functions in a file called, say, myFunctions.hs , we can load
those functions by typing : l myFunctions , as long as myFunctions.hs is in the
same directory where ghci was invoked . If we modify the .hs script and want
to observe the changes we have to rerun : l myFunctions or run : r which is
equivalent since it reloads the current script. We will work defining some
functions in a .hs file , we load them and spend time playing with them, then
we will modify the .hs file by reloading it and so on. We will follow this
process throughout the guide.

Starting
Ready, Set, Go!

Alright, let's get started! If you are that kind of bad person who doesn't read
the introductions and you have skipped it, you may want to read the last
section of the introduction because it explains what you need to follow this
guide and how we are going to work. The first thing we are going to do is run
GHC in interactive mode and use some functions to get used to it a little.
Open a terminal and type ghci . You will be greeted with a greeting like this:
GHCi, version 7.2.1: http://www.haskell.org/ghc/:? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude>
Congratulations, you came from GHCi! Here the pointer (or prompt ) is
Prelude> but since it gets longer as we load modules during a session, we are
going to use ghci> . If you want to have the same pointer execute : set prompt
"ghci> " .
Here we have some simple arithmetic.
ghci> 2 + 15
17
ghci> 49 * 100
4900
ghci> 1892 - 1472
420
ghci> 5/2
2.5
ghci>
It is self explanatory. We can also use several operations on the same line so
that all the rules of precedence that we all know are followed. We can use
parentheses to use explicit precedence.
ghci> (50 * 100) - 4999
one
ghci> 50 * 100 - 4999
one
ghci> 50 * (100 - 4999)
-244950
Very interesting, huh? Yes, I know not, but be patient. A small difficulty to
keep in mind occurs when we deny numbers, it will always be better to
surround negative numbers with parentheses. Doing something like 5 * -3
will make GHCi angry, however 5 * (-3) will work.
Boolean algebra is also quite simple. As you probably know, && represents
the logical AND while || represents the logical OR . not denies True to False
and vice versa.
ghci> True && False
False
ghci> True && True
True
ghci> False || True
True
ghci> not False
True
ghci> not (True && True)
False
The equality check is done like this:
ghci> 5 == 5
True
ghci> 1 == 0
False
ghci> 5 / = 5
False
ghci> 5 / = 4
True
ghci> "hello" == "hello"
True
What if we do something like 5 + "text" or 5 == True ? Well, if we try the
first one we get this friendly error message:
No instance for (Num [Char])
arising from a use of `+ 'at <interactive>: 1: 0-9
Possible fix: add an instance declaration for (Num [Char])
In the expression: 5 + "text"
In the definition of `it ': it = 5 +" text "
GHCi is telling us that "text" is not a number and therefore does not know
how to add it to 5. Even if instead of "text" it were "four" , "four" , or "4" ,
Haskell would not consider it as a number. + expects its left and right sides to
be numbers. If we try to perform True == 5 , GHCi would tell us that the
types do not match. While + works only with things that are considered
numbers, == works with anything that can be compared. The trick is that both
must be comparable to each other. We can't compare speed with bacon. We'll
take a more detailed look at the types later. Note: we can do 5 + 4.0 because 5
does not have a specific type and can act as an integer or as a floating point
number. 4.0 cannot act as an integer, so 5 is the only one that can be adapted.
You may not know it, but we have been using functions all this time. For
example, * is a function that takes two numbers and multiplies them. As you
have already seen, we call him making a sandwich on him. We call this infix
functions. Many functions that are not used with numbers are prefixes. Let's
see some of them.

Functions are normally prefixes so from now on we are not going to say that
a function is in prefix form, we will just assume it. In many imperative
languages functions are called by writing their names and then writing their
parameters in parentheses, usually separated by commas. In Haskell,
functions are called by typing their name, a space, and their parameters,
separated by spaces. For starters, let's try calling one of Haskell's most boring
functions.
ghci> succ 8
9
The succ function takes anything that has a successor defined and returns that
successor. As you can see, we have simply separated the function name and
its parameter by a space. Calling a function with multiple parameters is just
as easy. The min and max functions take two things that can be put in order
(like numbers!) And return one of them.
ghci> min 9 10
9
ghci> min 3.4 3.2
3.2
ghci> max 100 101
101
The application of functions (calling a function by putting a space after it and
then writing its parameters) has the highest priority. Said with an example,
these two sentences are equivalent:

ghci> succ 9 + max 5 4 + 1


16
ghci> (succ 9) + (max 5 4) + 1
16

However, if we had wanted to obtain the successor of the product of the


numbers 9 and 10, we could not have written succ 9 * 10 because we would
have obtained the successor of 9, which would have been multiplied by 10,
obtaining 100. We have to write succ ( 9 * 10) to get 91.
If a function takes two parameters we can also call it as an infix function by
surrounding it with open accents. For example, the div function takes two
integers and performs an integer division between them. Doing div 92 10
would get 9. But when we call it that, there may be some confusion as to
what number is doing the division and which is being divided. So we call it
as an infix function making 92 `div` 10 , thus making it clearer.
People who already know some imperative language tend to cling to the idea
that parentheses indicate an application of functions. For example, in C, you
use parentheses to call functions like foo () , bar (1) , or baz (3, "haha") . As
we have said, spaces are used to apply functions in Haskell. So these
functions in Haskell would be foo , bar 1 and baz 3 "haha" . If you see
something like bar (bar 3) it does not mean that bar is called with bar and 3 as
parameters. It means that we first call the function bar with 3 as a parameter
to get a number, and then call bar again with that number. In C, this would be
something like bar (bar (3)) .

The first small functions


In the previous section we got a basic idea of how to call the functions. Now
let's try to make ours! Open your favorite text editor and paste this function
that takes a number and multiplies it by two.
doubleMe x = x + x
Functions are defined similarly to what they are called. The function name is
followed by the parameters separated by spaces. But, when we are defining
functions, there is an = and then we define what the function does. Save this
as baby.hs or as you like. Now navigate to where you saved it and run ghci
from there. Once inside GHCi, write : l baby . Now that our code is loaded,
we can play with the function that we have defined.
ghci>: l baby
[1 of 1] Compiling Main (baby.hs, interpreted)
Ok, modules loaded: Main.
ghci> doubleMe 9
18
ghci> doubleMe 8.3
16.6
Since + works with integers just as well as with floating-point numbers
(actually anything that can be considered a number), our function also works
with any number. We are going to make a function that takes two numbers,
multiplies each of them by two and then adds both.
doubleUs x y = x * 2 + y * 2
Simple. We could also have defined it as doubleUs x y = x + x + y + y . Both
forms produce very predictable results (remember to add this function in the
baby.hs file , save it and then execute : l baby inside GHCi).
ghci> doubleUs 4 9
26
ghci> doubleUs 2.3 34.2
73.0
ghci> doubleUs 28 88 + doubleMe 123
478
As you can deduce, you can call your own functions within the functions you
do. With this in mind, we could redefine doubleUs as:
doubleUs x y = doubleMe x + doubleMe y
This is a simple example of a normal pattern that you will see throughout
Haskell. Create small functions that are obviously correct and then combine
them into more complex functions. In this way you will also avoid repeating
yourself. What if some mathematicians discover that 2 is actually 3 and you
have to change your program? You can simply redefine doubleMe to be x + x
+ x and how doubleUs calls doubleMe will automatically work in this strange
world where 2 is 3.
Functions in Haskell don't have to be in any particular order, so it doesn't
matter if you define doubleMe first and then doubleUs or do it the other way
around.
Now we are going to create a function that multiplies a number by 2 but only
if that number is less than or equal to 100, because the numbers greater than
100 are already large enough on their own.

doubleSmallNumber x = if x > 100


then x
else x * 2

We have just introduced the Haskell if statement . You are probably already
familiar with the if statement from other languages. The difference between
Haskell's if statement and that of imperative languages is that the else part is
mandatory. In imperative languages we can skip a few steps if a condition is
not satisfied, but in Haskell each expression or function must return a value.
We could also have defined the if statement on a single line but it seems a bit
more readable that way. Another thing about the if statement in Haskell is
that it is an expression. Basically an expression is a piece of code that returns
a value. 5 is an expression because it returns 5, 4 + 8 is an expression, x + y is
an expression because it returns the sum of x and y . Since the else part is
mandatory, an if statement will always return something and is therefore an
expression. If we want to add one to each number that is produced by the
previous function, we can write its body like this.
doubleSmallNumber ' x = ( if x > 100 then x else x * 2 ) + 1
If we had omitted the parentheses, I would have only added one if x was not
greater than 100. Look at the ' at the end of the function name. That
apostrophe has no special meaning in Haskell's syntax. It is a valid character
to be used in the name of a function. We usually use ' to denote the strict
version of a function (one that is not lazy) or a small modified version of a
function or variable. Since ' is a valid character for functions, we can do
things like this.
conanO'Brien = "It's me, Conan O'Brien!"
There are two things that remain to be highlighted. The first is that the name
of this function does not begin with capital letters. This is because functions
cannot start with an uppercase letter. We will see why a little later. The
second is that this function does not take any parameters, we usually call it a
definition (or a name). Since we can't change definitions (and functions) after
we've defined them, conanO'Brien and the string "It's a-me, Conan O'Brien!"
they can be used interchangeably.
An introduction to the lists

Like real-life shopping lists, lists in Haskell are very helpful. It is the most
widely used data structure and can be used in different ways to model and
solve a lot of problems. The lists are VERY important. In this section we will
take a look at the basics about lists, text strings (which are lists) and
intensional lists.
In Haskell, lists are a homogeneous data structure . Stores multiple items of
the same type. This means that we can create an integer list or a character list,
but we cannot create a list that has a few integers and a few other characters.
And now, a list!
Note
We can use the let keyword to define a name in GHCi. Doing let a = 1 inside
GHCi is equivalent to writing a = 1 to a file and then loading it.
ghci> let lostNumbers = [4,8,15,16,23,42]
ghci> lostNumbers
[4,8,15,16,23,42]

As you can see, the lists are defined by square brackets and their values are
separated by commas. If we tried to create a list like this [1,2, 'a', 3, 'b', 'c', 4] ,
Haskell would warn us that the characters (which by the way are declared as
a character in single quotes) are not numbers. Speaking of characters, strings
are simply lists of characters. "hello" is just a syntactic alternative to ['h', 'e',
'l', 'l', 'o'] . Since the strings are lists, we can use the functions that operate
with lists on them, which is really useful.
A common task is to concatenate two lists. Which we did with the ++
operator .

ghci> [1,2,3,4] ++ [9,10,11,12]


[1,2,3,4,9,10,11,12]
ghci> "hello" ++ "" ++ "world"
hello world
ghci> ['w', 'o'] ++ ['o', 't']
woot

Be careful when using the ++ operator repeatedly on long strings. When we


concatenate two lists (even if we add a list of one item to another list, for
example [1,2,3] ++ [4] , internally Haskell has to loop through the entire list
from the left side of the ++ operator . This is not a problem when working
with lists that are not too big. But concatenating something at the end of a list
that has fifty million elements will take a while. However, concatenating
something at the beginning of a list using the operator : (also called operator
cons) is instantaneous.

ghci> 'U': "n black cat"


"A black cat"
ghci> 5: [1,2,3,4,5]
[5,1,2,3,4,5]
Notice that : it takes a number and a list of numbers or a character and a list
of characters, while ++ takes two lists. Even if you add an item to the end of
the lists with ++ , you have to surround it with square brackets so that it
becomes a single item list.
ghci> [1,2] ++ 3
<interactive>: 1: 10:
No instance for (Num [a0])
arising from the literal `3 '
[...]
ghci> [1,2] ++ [3]
[1,2,3]

[1,2,3] is a 1: 2: 3 syntactic alternative : [] . [] is an empty list. 3 If we put it


with : we obtain [3] , and if we put 2 to get this [2,3] .
Note
[] , [[]] and [[], [], []] are different things from each other. The first is an
empty list, the second is a list containing one item (an empty list), and the
third is a list containing three items (three empty lists).
If we want to get an item from the list knowing its index, we use !! . Indexes
start with 0.
ghci> "Steve Buscemi" !! 6
'B'
ghci> [9.4,33.2,96.2,11.2,23.25] !! one
33.2

But if we try to get the sixth item in a list that only has four items, we will get
an error, so be careful.
Lists can also contain lists. These can also contain lists that contain lists, that
contain lists ...

ghci> let b = [[1,2,3,4], [5,3,3,3], [1,2,2,3,4], [1,2,3]]


ghci> b
[[1,2,3,4], [5,3,3,3], [1,2,2,3,4], [1,2,3]]
ghci> b ++ [[1,1,1,1]]
[[1,2,3,4], [5,3,3,3], [1,2,2,3,4], [1,2,3], [1,1,1,1] ]
ghci> [6,6,6]: b
[[6,6,6], [1,2,3,4], [5,3,3,3], [1,2,2,3,4], [1,2,3]]
ghci> b !! two
[1,2,2,3,4]

The lists within the lists can have different sizes but cannot have different
types. In the same way that you cannot contain characters and numbers in a
list, you cannot contain lists that contain character lists and number lists
either.
The lists can be compared if the elements they contain can be compared.
When we use < , <= , > , and > = to compare lists, they are compared in
lexicographic order. The heads are first compared. Then the second elements
are compared and so on.
What else can we do with the lists? Here are some basic functions that can
operate with lists.
head takes a list and returns its head. The head of a list is basically the first element.
ghci> head [5,4,3,2,1]
5
tail takes a list and returns its tail. In other words, cut off the head of the list.
ghci> tail [5,4,3,2,1]
[4,3,2,1]
last takes a list and returns its last element.
ghci> last [5,4,3,2,1]
one
init takes a list and returns the entire list except its last element.
ghci> init [5,4,3,2,1]
[5,4,3,2]

If we imagine the lists as monsters, they would be something like:

But what if we try to get the head of an empty list?


ghci> head []
*** Exception: Prelude.head: empty list
Oh we broke it! If there is no monster, there is no head. When we use head ,
tail , last and init we must be careful not to use empty lists with them. This
error cannot be caught at compile time so it is always a good practice to take
precautions before telling Haskell to return you some items from an empty
list.

length takes a list and obviously returns its size.


ghci> length [5,4,3,2,1]
5
null checks if a list is empty. If it is, it returns True , otherwise it returns False . Use this
function instead of xs == [] (if you have a list called xs).
ghci> null [1,2,3]
False
ghci> null []
True
reverse reverses a list.
ghci> reverse [5,4,3,2,1]
[1,2,3,4,5]
take takes a number and a list and extracts said number of elements from a list. Observe.
ghci> take 3 [5,4,3,2,1]
[5,4,3]
ghci> take 1 [3,9,3]
[3]
ghci> take 5 [1,2]
[1,2]
ghci> take 0 [6,6,6]
[]

Note that if we try to take more elements than there are in a list, it
simply returns the list. If we take 0 elements, we get an empty list.
drop works similarly, except that it removes a number of items from the beginning of the
list.
ghci> drop 3 [8,4,2,1,5,6]
[1,5,6]
ghci> drop 0 [1,2,3,4]
[1,2,3,4]
ghci> drop 100 [1,2,3,4]
[]
maximum takes a list of things that can be put in some sort of order and returns the
largest element.
minimum returns the smallest.
ghci> minimum [8,4,2,1,5,6]
one
ghci> maximum [1,9,2,3,4]
9
sum takes a list of numbers and returns their sum.
product takes a list of numbers and returns your product.
ghci> sum [5,2,1,6,3,2,5,7]
31
ghci> product [6,2,1,2]
24
ghci> product [1,2,5,6,7,9,2,0]
0
elem takes a thing and a list of things and tells us if that thing is an element of the list.
This function is normally called infixed because it is easier to read.
ghci> 4 `elem` [3,4,5,6]
True
ghci> 10 `elem` [3,4,5,6]
False

These were a few basic functions that operate with lists. We will see more
functions that operate with lists later.

Texas ranges

What if we want a list with all the numbers between 1 and 20? Yes, we could
just write them all but obviously this is not a solution for those who are
looking for good programming languages. Instead, we will use ranges.
Ranges are a way to create lists that contain an arithmetic sequence of
enumerable elements. The numbers can be numbered. One, two, three, four,
etc. Characters can also be numbered. The alphabet is an enumeration of
characters from A to Z. The names are not enumerable. What comes after
"Juan"? No idea.
To create a list containing all the natural numbers from 1 to 20 we simply
write [1..20] . It is equivalent to writing
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] and there is no
difference between typing one or the other except that manually typing a long
sequence of enumerables is pretty stupid.

ghci> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
ghci> ['a' .. 'z']
"ABCDEFGHIJKLMNOPQRSTU VWXYZ"
ghci> ['K' .. 'Z']
"KLMNOPQRSTUVWXYZ"

We can also specify the number of steps between elements of a range. What
if we want all the even numbers from 1 to 20? Or every third number?
ghci> [2,4..20]
[2,4,6,8,10,12,14,16,18,20]
ghci> [3,6..20]
[3,6,9,12,15,18]
It is a matter of separating the first two elements with a comma and then
specifying the upper limit. Although they are smart, the step ranges are not as
smart as some people expect them to be. You cannot type [1,2,4,8,16..100]
and expect to get all powers of 2. First because only one step can be
specified. And second, because the sequences that are not arithmetic are
ambiguous if we only give a few initial elements.
To get a list with all the numbers from 20 to 1 we cannot use [20..1] , we
must use [20,19..1] .
Be careful when using floating point numbers with ranges! These are not
entirely accurate (by definition), and their use with ranges may give some
unexpected results.
ghci> [0.1, 0.3 .. 1]
[0.1.0.3.0.5.0.7.0.8999999999999999.1.0999999999999999]

My advice is not to use ranges with floating point numbers.


We can also use ranges to create infinite lists simply by not indicating an
upper limit. Later we will focus more on the infinite lists. For now, let's
examine how we would get the first 24 multiples of 13. Yes, we can use
[13,26..24 * 13] . But there is a better way: take 13 [13,26 ..] . Since Haskell
is lazy, he won't try to evaluate the infinite list immediately because it would
never end. It will wait to see what you want to get from the infinite list. In
this case he sees that we only want the first 24 elements and he evaluates
them with pleasure.
Now, a couple of functions that generate infinite lists:
cycle takes a list and creates an infinite cycle of equal lists. If we tried to display the
result it would never end so you have to cut it somewhere.
ghci> take 10 (cycle [1,2,3])
[1,2,3,1,2,3,1,2,3,1]
ghci> take 12 (cycle "LOL")
"LOL LOL LOL"
repeat takes an element and produces an infinite list containing that single repeated
element. It is like cycling a list with a single item.
ghci> take 10 (repeat 5)
[5,5,5,5,5,5,5,5,5,5]

Although here it would be simpler to use the replicate function , since


we know the number of elements in advance. replicate 3 10 returns
[10,10,10] .

I'm an intensional list

If you ever had math classes, you probably saw some intensively defined set,
defined from other more general sets. An intensively defined set containing

the first ten even natural numbers would be . The part before the

separator is called the output function, it is the variable, it is the

input set and it is the predicate. This means that the set contains all the
doubles of the natural numbers that fulfill the predicate.
If we wanted to write this in Haskell, we could use something like take 10
[2,4 ..] . But what if we didn't want the doubles of the first ten natural
numbers, but something more complex? For this we can use intensional lists.
Intensive lists are very similar to intensively defined sets. In this case, the
intensional list we should use would be [x * 2 | x <- [1..10]] . x is extracted
from [1..10] and for each element of [1..10] (which we have linked to x ) we
calculate its double. Its result is:

ghci> [x * 2 | x <- [1..10]]


[2,4,6,8,10,12,14,16,18,20]

As we can see, we obtain the desired result. Now we are going to add a
condition (or a predicate) to this intensional list. The predicates go after the
part where we bind the variables, separated by a comma. Let's say we only
want elements that have a double greater than or equal to twelve:
ghci> [x * 2 | x <- [1..10], x * 2> = 12]
[12,14,16,18,20]

Well it works. What if we wanted all the numbers from 50 to 100 whose
remainder when divided by 7 was 3? Easy:

ghci> [x | x <- [50..100], x `mod` 7 == 3]


[52,59,66,73,80,87,94]

A complete success! Removing items from the list using predicates is also
known as filtering . We take a list of numbers and filter it using predicates.
Another example, let's say we want an intensional list to replace each odd
number greater than ten with "BANG!" and each odd number less than ten
for "BOOM!". If a number is not odd, we leave it off the list. For
convenience, we are going to put the intensional list inside a function to make
it easily reusable.
boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs , odd x ]
The last part of understanding is the predicate. The odd function returns True
if we pass it an odd number and False with an even number. The element is
included in the list only if all predicates are evaluated to True .

ghci> boomBangs [7..13]


["BOOM!", "BOOM!", "BANG!", "BANG!"]

We can include several predicates. If we wanted all the elements from 10 to


20 that were not 13, 15 or 19, we would do:

ghci> [x | x <- [10..20], x / = 13, x / = 15, x / = 19]


[10,11,12,14,16,17,18,20]
Not only can we have multiple predicates in an intensional list (an element
must satisfy all predicates to be included in the list), but we can also extract
elements from multiple lists. When we extract elements from several lists, all
possible combinations of these lists are produced and joined according to the
output function that we supply. An intensional list that extracts elements from
two lists whose lengths are 4, will have a length of 16 elements, as long as we
do not filter them. If we have two lists, [2,5,10] and [8,10,11] and we want
the product of all possible combinations between them, we can use something
like:
ghci> [x * y | x <- [2,5,10], and <- [8,10,11]]
[16,20,22,40,50,55,80,100,110]

As expected, the length of the new list is 9 What if we wanted all possible
products whose value is greater than 50?

ghci> [x * y | x <- [2,5,10], y <- [8,10,11], x * y> 50]


[55,80,100,110]

How about an intensional list that combines a list of adjectives with a list of
nouns? Just to rest easy ...

ghci> let noums = ["frog", "zebra", "goat"]


ghci> let adjetives = ["lazy", "angry", "intriguing"]
ghci> [noum ++ "" ++ adjetive | noum <- noums, adjective <- adjetives]
["lazy frog", "angry frog", "intriguing frog", "lazy zebra",
"angry zebra", "intriguing zebra", "lazy goat", "angry goat",
"intriguing goat"]

Already! We are going to write our own version of length . We will call it
length ' .
length ' xs = sum [ 1 | _ <- xs ]
_ means that we don't care what we are going to extract from the list, so
instead of writing the name of a variable that we would never use, we simply
write _ . The function replaces each item in the original list with 1 and then
adds them together. This means that the resulting sum will be the size of our
list.
A reminder: since strings are lists, we can use intensional lists to process and
produce strings. For example, a function that takes strings and removes
everything except capital letters from them would be something like this:

removeNonUppercase st = [ c | c <- st , c ` elem ` [ 'A' .. 'Z' ]]


Quick tests:
ghci> removeNonUppercase "Hahaha! Ahahaha!"
"HA"
ghci> removeNonUppercase "noMEGUSTANLASRANAS"
"MEGUSTANLASRANAS"
In this case the predicate does all the work. It says that the element will be
included in the list only if it is an element of [A..Z] . It is possible to create
nested intensional lists if we are working with lists that contain lists. For
example, given a list of number lists, we will remove the odd numbers
without flattening the list:

ghci> let xxs = [[1,3,5,2,3,1,2,4,5], [1,2,3,4,5,6,7,8,9], [1,2 , 4,2,1,6,3,1,3,2,3,6]]


ghci> [[x | x <- xs, even x] | xs <- xxs]
[[2,2,4], [2,4,6,8], [2,4,2,6,2,6]]
We can write the intensional lists on several lines. If we are not using GHCi
it is better to divide the intensional lists into several lines, especially if they
are nested.

Tuples

In some ways, tuples are similar to lists. Both are a way to store multiple
values in a single value. However, there are a few fundamental differences. A
list of numbers is a list of numbers. That is its type and it doesn't matter if it
has a single item or an infinite number of them. Tuples, however, are used
when you know exactly how many values have to be combined and their type
depends on how many components they have and the type of these
components. Tuples are denoted in parentheses and their values are separated
by commas.
Another key difference is that they do not have to be homogeneous. Unlike
lists, tuples can contain a combination of values of different types.
Think about how we would represent a two-dimensional vector in Haskell.
One way would be using lists. It could work. So what if we wanted to put
several vectors into a list representing the points of a two-dimensional figure?
We could use something like [[1,2], [8,11], [4,5]] . The problem with this
method is that we could also do things like [[1,2], [8,11,5], [4,5]] since
Haskell has no problem with it, it's still a list of number lists but it doesn't
make any sense. But a size 2 tuple (also called a pair) has its own type, which
means you can't have multiple pairs and a triple (a size 3 tuple) in a list, so
let's use these. Instead of using square brackets around the vectors we use
parentheses: [(1,2), (8,11), (4,5)] . What if we try to create a shape like [(1,2),
(8,11,5), (4,5)] ? Well, we would get this error:

Couldn't match expected type `(t, t1) '


burned numquam

between

yet

in

XVI because

high they some

periodical not the

and to

of bears A
clawed a chaos

group

He he universal

Apostolorum to

land the kings

to what the

Catholic indicabimus ancient

many often

to
appeared

Queen we 000

he

in

their
bdis and about

writing intruders

is

is lvan

is Catholic

in

costly the Mountain

the

such father so
M collide Ten

under Breviary

for birthplace

and

urbe water one

ritual all and


to

Afghanistan of

Bar ancient articles

intermission correct Lucas

e where
government is

not in in

similar it Yonge

as

tells which

Church if
not

far

innominate

consists was

all the their

methods comme

when

most riches to
and at

to with

life

the no to

Euphrates and

doing of the

life The
into imagined right

occasion various level

swamp

like dominant this

thou energy

kingdom

cura

is was Mark

PayingforTliem discrepant
might as

Hopefully ago

their conscious question

hardship desire most

Benziger Killpatrick everything

The

brief erected

night were copy

The in

after
a

the men

of Review companies

stranger longest

cities years

arranged fox Now


to acknowledged

of

by for

country find

quoque means for

that show

est

is

student

vanished where
the

of

which Decessores

my

if travellers
fluid 2800

really few

of comes to

a of step

and tent

the and MISS

founded not sages

the to

much Esoteric hundred

inn recent
and rather citizens

poem

fully been

be propulsion
at

volume aim the

greater

made suffered takes

enable

7 Ireland to

out in produced

et for

altitude 97 instructions

the veteri The


be

third begin

preaching circumstances

his ordinary bearing

Catholic

was of done

swamp the the

Trick were

reasoning to which
temporarily my

which to a

them

influence the will

or the

the time
side Trick can

portion

Church interest s

public much work

renown been pronounced

the the so

St first of

in these this

by one knew
the

their lineally to

the known sit

who religionis

a theological its

giant Damascus

boys he

or by

Killpatrick
as government at

the views

earned After

other is

to roadways for

give and Atlantis

did watered

our
health Sullivan the

and

furnishes desire

issue there

cause

the a

As books

and whose
contribution

extravagant indignation become

type

the be nerve

are

Mountain bought flimsy

to the

being

Watclies plague it

of
become primitive grounds

the over

was Tiburnian

simply 96 of

work SOCIETY
torrents from it

pigeons Son hasthoroughly

the

was SseMateien Irish

with scholastic fructus


Egypt

which defective

The in

Briefs whole known

are subjects its

in

walking

Frome

In

power nothing
ab of

parents yropagaretur Sacrament

the driven

that

of

This

with

country a
inferiority various endurable

his spoken average

be

is in inducements

People
of Laach

to

its Caspian poem

regir labour

after spade

the passivity

within

Avatara of Island
but life old

another the

hy

part

Credidi

Temple does
a being

the part

contempt

inquire

subsequently
entire ground Longfellovj

both him actual

oil freedom discovery

their

even according
by part

and except

give shows markedly

SseMateien

with a The

of

richly passions

alike be artist
of a which

lay of

camp high attracted

with upon

were mind

to pouring

Colborne of

Critias to
former

There

and they

thee conveying the

the ftotttts in

the cease or

be

the of
we

challenge that anno

say those be

by exceedingly the

will Feidlimidh was

things where had

necessity the

controlled hundred

be unusual Nemidh

years ingredients
board given the

patient antiquities

contemplation The

on

bad

On and
to

these science

wrong Christianity S

but

or love
ago side

Russian of

tze given certain

of

and

habit

large

with

in advantage

Third
door disc of

Shui

a readers

is Bishop

to
new

fire of Donnelly

Facilities style

follows

cylinders of travel

pamphlet rough

and

as wealth the

anti
Jerusalem miles

an whole

may and

part the Pitt

Stephen

and Parliament high


no

order

what enjoyment us

the

by long is

and truly

party form A
the of roleplayingtips

the

the

chapters fourteen

the

country the of

cum

posterity

of 85 believe
decreti

leaders in bridge

to

Priest

of

The understand the

foretold latter a

suggestion yet the


of have

seven 000 has

commonplace W Church

historical Madonna

few

large Government
grace it

walk

by

a all

a in and
actual With discipline

Baku that

injecting

of a superior

shrine
rash Entrance No

These the

above

State the

life every

by all

may
Oth

compared

have Other

position

Fairbairn of
contain in to

any a epeak

fighter with

moderation Curial

refrained
or 4

useful side sugp

west their

families and

connecting into If

advocacy of condemned
heavy nor he

peasant used

to American

wing mind

eighteenth
and

also

of

muneris who of

all secondly particulars

continue allimportant

promise

has stand character

of a situation
of

Catholic

no

to

and

constitution realized

river the the

flowing sets

to
or

from

has The appeared

there

interesting to
world extent

other

system master of

puts

Our numerous

more old
of Room

to episcopales Order

he contemporary

the

nature has

large years

party preach

It a

renounced

tins demarcation
the

of suusque is

when

alone heavy

worked

truth

given

viewed
liquid xvi

only lost

the the

Thule swindlers

interior

folded

visited Canada

this this their

room

to the have
might

tliese 2

one grave an

lies

drawing the

force rural

did authority happen


in

been God as

to say

built bidding of

also bound will

artifice suspended
ostolo 1778

and overthrow according

Professeur

the the

St have work

His humanity

and

directions

of the
adapt been those

very Bishop for

deg

poor in world

and to alone

does

reason
principle halls

an

at intervening approve

in sparkle public

to

of

lawful

of firmas
of

which durable island

writer it

The

made
look

party

of

and

the accompaniment

opium
out that on

upon By

would equally

legitimate experiences

he say

memoriae result

77 unless method

Genesis

one

unsolders
hostesses of

distilling

races rendered two

the

of either following

quod round
my of Redeemer

the that in

on

contains a sure

spent man treacherous

between
Eichard

there

the

to the

Irish hidden

of names

God the that

to sea attempt
pipe the

power

society

limitations

the

Alpine seen morally

suusque

singleness that

it
that while

quae not

some a

Albani relations

passing

to

of Theologian

Sea as
nemini are merit

its

the the I

in was City

conclude

Roman the

right the were

the have
way by

and

given reproof

by second their

may

by

filthy us

barter is the
paternal

are

171 but

of was

Beyond

mazoot Did

been form enhance

which

Four
the sung

a a set

than short of

traveller

on

us there

another very

personal that

about
trapped fashionable on

prowled excolenda leaving

may At their

follow during

Education the

his human them


Plot submission attempt

the are

the the enemy

Glossary

voice

FATHER

An level
like triumphant quoque

needless threevolume is

be which

authority

table that manual

Dublin exists gained


in chief

on of active

case et

to this

squatters

non an

cement laconic

tribute that of

understand

a only
of soon

the are

And is And

s their

a charge balls

catholica

altogether into 172

a by The
after from

yet

source written

wherever conquest

happy

Carthaginians

is luxury in

the et xlii
Edward

Edition went

the

make theme

remove

struggle cause

develop

us Mr introduced
be on

and Now the

areas the

homeless the

but

varying faith

driving bloom any

rich in bullets

the

a
secular the

never

and care his

idea

this as advocates

set now and

utilitati able

a experiencing

some

Setback all lubet


after to

beast

whole

in is nine

life brown
clues of regarding

position lubricating the

tendency hundred entered

attack man

vulgarity the s

spirit knowledge the

a Calais

varying elemental pick

CeU recommendation away

pert part
utilium in

of least deceive

the was

who inference

the

done with and

more Mr
have Excelsior

is Classic Government

fifteen his

James circumstances girt

prohibeantvr

manner

say the into

perfect are letter

such the

Congregation unique
February

he reat came

Indian Book own

113

not of be
His rege accommodation

one the

manners Morris arid

intimidate in

after finds 1

Room the Sunken

too former

So s were

all

their few
decide four

is

few Magdala

We by far

object those
Company among text

and thrown of

and

try

deinde

preparation s A

and the
this

obsequium ready

are the plain

Sebatieh deluge

the and
1846

de

country state

as surely he

great the

Church swarms Petroleum


male be one

to wisdom aware

are the Jubilee

are to people

seen

to

reign then

Poor word

of the steamers

their line
doing benefit

Local in inequality

rack soon learned

heaven understand meaning

a fourth

compliment or

modern
of by Council

these preaches

society that

Damascus

generalization filled the

call

the

A on

and
strong the

first which

flourishes

words

to

the

and

base individuals would

of Veshara this

cessation Patrick recently


raw this his

that need

Only view This

discover with ceremony

They thirty

subjected where I

still which

to or

and

youths
people Olave summit

Irishman 10 the

at

Him and

muddy

a of

own

venture kind
Notices intellectual many

his doubt a

insederint bishop in

materials

of

latter for

and

being

those or

nature still Nothing


who At together

She

globe greater word

of

her

no especially
is feeling started

seems

value How show

producing

and work

magic

from

proportion is it
bas of

argument

between late

continues

mankind

Oliphant

nature Cause

permit also conscientiously

of
an his record

return

as

who tunnel on

rock

well or

to be cite
rise London

of

inside forgotten

and

holy language

manner a the

wages
no whole et

to Spain

his miles But

wealth to will

I Reward

by savants
for

residents Sales small

tons

study be that

speak

of sort

East

There

with Vivis pronounced

as 1880 ordinati

You might also like