Haskell Crash Course Part III

Writing Applications

Lets write the classic “Hello world!” program.

For example, in Python you may write:

and then you can run it:












Haskell is a Pure language.

Not a value judgment, but a precise technical statement:

The “Immutability Principle”:

  • A function must always return the same output for a given input

  • A function’s behavior should never change









No Side Effects

Haskell’s most radical idea: expression =*> value

  • When you evaluate an expression you get a value and

  • Nothing else happens

Specifically, evaluation must not have an side effects

  • change a global variable or

  • print to screen or

  • read a file or

  • send an email or

  • launch a missile.









But… how to write “Hello, world!”

But, we want to …

  • print to screen
  • read a file
  • send an email

Thankfully, you can do all the above via a very clever idea: Recipe









Recipes

This analogy is due to Joachim Brietner

Haskell has a special type called IO – which you can think of as Recipe

A value of type Recipe a

  • is a description of a computation that can have side-effects

  • which when executed performs some effectful I/O operations

  • to produce a value of type a.









Recipes have No Side Effects

A value of type Recipe a is

  • A description of a computation that can have side-effects
Cake vs. Recipe
Cake vs. Recipe

(L) chocolate cake, (R) a sequence of instructions on how to make a cake.

They are different (Hint: only one of them is delicious.)

Merely having a Recipe Cake has no effects! The recipe

  • Does not make your oven hot

  • Does not make your your floor dirty









Only One Way to Execute Recipes

Haskell looks for a special value

The value associated with main is handed to the runtime system and executed

Baker Aker
Baker Aker

The Haskell runtime is a master chef who is the only one allowed to cook!









How to write an App in Haskell

Make a Recipe () that is handed off to the master chef main.

  • main can be arbitrarily complicated

  • composed of smaller sub-recipes









A Recipe to Print to Screen

The function putStrLn

  • takes as input a String
  • returns as output a Recipe ()

putStrLn msg is a Recipe () - when executed prints out msg on the screen.

… and we can compile and run it









QUIZ: How to Print Multiple Things?

Suppose I want to print two things e.g.

Can we try to compile and run this:

A. Yes!

B. No, there is a type error!

C. No, it compiles but produces a different result!









A Collection of Recipes

Is just … a collection of Recipes!

… we need a way to combine recipes!









Combining? Just do it!

We can combine many recipes into a single one using a do block

(or if you prefer curly braces to indentation)

The do block combines sub-recipes r1, r2 and r3 into a new recipe that

  • Will execute each sub-recipe in sequence and
  • Return the value of type a3 produced by the last recipe r3









Combining? Just do it!

So we can write

or if you prefer









EXERCISE: Combining Many Recipes

Write a function called sequence that

  • Takes a list of recipes [r1,...,rn] as input and
  • Returns a single recipe equivalent to do {r1; ...; rn}

When you are done you should see the following behavior

and then









Using the Results of (Sub-) Recipes

Suppose we want a function that asks for the user’s name

We can use the following sub-recipes

But how to

  • Combine the two sub-recipes while
  • Passing the result of the first sub-recipe to the second.









Naming Recipe Results via “Assignment”

You can write

to name the result of executing recipe

  • x can be used to refer to the result in later code









Naming Recipe Results via “Assignment”

Lets, write a function that asks for the user’s name

Which produces the desired result









EXERCISE

Modify the above code so that the program repeatedly asks for the users’s name until they provide a non-empty string.

When you are done you should get the following behavior









EXERCISE

Modify your code to also print out a count in the prompt

That’s all about IO

You should be able to implement build from Directory.hs

Using these library functions imported at the top of the file

The functions are

  • takeDirectory
  • takeFileName
  • (</>)
  • doesFileExist
  • listDirectory

hoogle the documentation to learn about how to use them.