Part 1: Introduction

In this first part of the course, we will provide an overview of the Haskell language, introducing briefly all the most important concepts that set Haskell apart from other programming language.

All these concepts will be discussed in greater detail in the other parts of the course.

Accompanying materials

1–1 Welcome

In this video, I, Andres Löh, the lecturer of this course, introduce myself, and I explain the structure of the course.

Self Test

  • For every video, there will be a few “self test” exercises. These, you should be able to easily do if you have watched and understood the video. You do not have to submit these exercises, but if you have difficulties doing them, or are uncertain whether you have done them correctly, it is a clear indication that you should ask for help.

1–2 Expressions

Expressions are – in essence – possibly nested terms built from constants and functions calls and form probably the most important part of the Haskell language.

In this video, we introduce expressions by example, and discuss the syntax of function calls.

Self Test

  • Start GHCi and type in some examples from this video. Convince yourself that you get the same results.

  • What is the result of typing replicate 3 'x' into GHCi?

1–3 Types

Haskell is a statically typed language, and types play and important role. We introduce the some widely used types and discuss how function types make use of currying.

The type system comes with many features that enable code reuse, such as parametric polymorphism and overloading. Both are briefly discussed in this video.

We also briefly mention how Haskell handles code that has side effects, namely by making side effects visible in the type system.

Self Test

  • Start GHCi and type in some examples from this video. Convince yourself that you get the same results.

  • What is the result of :t words in GHCi? Try to figure out what the function words does by applying it to some inputs.

  • Note that GHCi has a :doc command. Try :doc words. Does the explanation given match what you’ve been figuring out?

  • What do you think the type of replicate is, based on your experiences in the self-test questions of the previous video? Does the :t command confirm your expectations?

1–4 Datatypes and Functions

We discuss how to make bindings to define new constants and functions. We also discuss how to introduce a new simple enumeration type and how to define a function that operates on this type by means of pattern matching.

Self Test

  • Open an editor, make the binding for double as shown in the video, save the source file, load the file into GHCi, and successfully call double 5 to obtain the result 10.

  • Make a binding triple in the same source file that triples a number according to the same principle as double, and test it in GHCi.

  • Type in the distance function into your source file as shown in the video, including the type signature. Use the function in GHCi after reloading, and also try :t distance to see that the inferred type matches the specified type signature.

  • Type in the datatype Choice as shown in the video, including the deriving clause, and define a function worsen according to the same principles as improve that maps Rock to Scissors, Paper to Rock, and Scissors to Paper.

  • Convince yourself that for all elements x of type Choice, calling worsen (improve x) yields x again.

1–5 Pattern Matching

We continue our discussion of pattern matching and define functions via pattern matching on Booleans and lists. We introduce our own list type to understand the structure of Haskell’s built-in lists better.

Self Test

  • Try to define the logical and operator (&&) by pattern matching, similar to how we defined (||) in the video.

  • Implement the List datatype as shown in the video, and implement the elem function both on the List datatype and on the type of built-in lists, both as shown in the video.

  • By modifying the elem function, can you turn it into a function that checks whether all elements in the list are equal to the given element?

1–6 Equational Reasoning and Lazy Evaluation

We demonstrate how to reason about evaluation by performing step-by-step reduction, so-called equational reasoning. We also see how Haskell always selects the outermost function call for reduction, implying that function arguments are only actually evaluated when required to make progress.

Self Test

  • Try take 10 [1..] and observe that it works.

  • Try [1..] and stop evaluation with Ctrl+C.

  • What does takeWhile (\ x -> x < 100) (map (\ x -> x * x) [1..]) do?

Continue this course

Next: Part 2: Datatypes and Functions.