# Hello, world! (The IO Monad)

## Writing Applications

In most language related classes, we start with a “Hello world!” program.

With 130, we will end with it.

## Purity and the Immutability Principle

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

• send an email or

• launch a missile.

## Purity

Means functions may depend only on their inputs

• i.e. functions should give the same output for the same input every time.

## But… how to write “Hello, world!”

But, we want to …

• print to screen
• send an email

A language that only lets you write `factorial` and `fibonacci` is … not very useful!

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`

``type Recipe a = IO a``

A value of type `Recipe a` is

• a description of an effectful computations

• when when executed (possibly) perform some effectful I/O operations to

• produce a value of type `a`.

## Recipes have No Effects

A value of type `Recipe a` is

• Just a description of an effectful computation

• An inert, perfectly safe thing with no effects.

(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: holding the recipe

• Does not make your oven hot

## Executing Recipes

There is only one way to execute a `Recipe a`

Haskell looks for a special value

``main :: Recipe ()``

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

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

• will be composed of many smaller recipes

## Hello World

``putStrLn :: String -> Recipe ()``

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.

``````main :: Recipe ()
main = putStrLn "Hello, world!"``````

… and we can compile and run it

``````\$ ghc --make hello.hs
\$ ./hello
Hello, world!``````

## QUIZ: Combining Recipes

Next, lets write a program that prints multiple things:

``````main :: IO ()
main = combine (putStrLn "Hello,") (putStrLn "World!")

-- putStrLn :: String -> Recipe ()
-- combine  :: ???``````

What must the type of `combine` be?

``````{- A -} combine :: () -> () -> ()
{- B -} combine :: Recipe () -> Recipe () -> Recipe ()
{- C -} combine :: Recipe a  -> Recipe a  -> Recipe a
{- D -} combine :: Recipe a  -> Recipe b  -> Recipe b
{- E -} combine :: Recipe a  -> Recipe b  -> Recipe a``````

## Using Intermediate Results

Next, lets write a program that

1. Asks for the user’s `name` using
``    getLine :: Recipe String``
1. Prints out a greeting with that `name` using
``    putStrLn :: String -> Recipe ()``

Problem: How to pass the output of first recipe into the second recipe?

## QUIZ: Using Yolks to Make Batter

Suppose you have two recipes

``````crack     :: Recipe Yolk
eggBatter :: Yolk -> Recipe Batter``````

and we want to get

``````mkBatter :: Recipe Batter
mkBatter = crack `combineWithResult` eggBatter``````

What must the type of `combineWithResult` be?

``````{- A -} Yolk -> Batter -> Batter
{- B -} Recipe Yolk -> (Yolk  -> Recipe Batter) -> Recipe Batter
{- C -} Recipe a    -> (a     -> Recipe a     ) -> Recipe a
{- D -} Recipe a    -> (a     -> Recipe b     ) -> Recipe b
{- E -} Recipe Yolk -> (Yolk  -> Recipe Batter) -> Recipe ()``````

## Looks Familiar

Wait a bit, the signature looks familiar!

``combineWithResult :: Recipe a -> (a -> Recipe b) -> Recipe b``

Remember this

``(>>=)             :: Result a -> (a -> Result b) -> Result b``

## `Recipe` is an instance of `Monad`

In fact, in the standard library

``````instance Monad Recipe where
(>>=) = {-... combineWithResult... -}``````

So we can put this together with `putStrLn` to get:

``````main :: Recipe ()
main = getLine >>= \name -> putStrLn ("Hello, " ++ name ++ "!")``````

or, using `do` notation the above becomes

``````main :: Recipe ()
main = do name <- getLine
putStrLn ("Hello, " ++ name ++ "!")``````

## EXERCISE

1. Compile and run to make sure its ok!

2. Modify the above to repeatedly ask for names.

3. Extend the above to print a “prompt” that tells you how many iterations have occurred.

• Error handling in `go` e.g. 1 and 2

• Asynchrony in JavaScript e.g. 1 and 2

• Big data pipelines e.g. LinQ and TensorFlow

## A Silly App to End CSE 130

Lets write an app called moo inspired by cowsay

A Command Line App

`moo` works with pipes