Introduces three distinct features of Haskell: laziness, type class, and monad.

A function is

strictin an argument if the result is undefined whenever an undefined value is passed to this argument. For instance,`(+)`

is strict in both arguments, while (&&) is strict in its first only. Recall that it is defined by`True && x = x False && x = False`

…

If a function is not strict in an argument, we say that it is

non-strictorlazyin that argument.

– Haskell: The Craft of Function Programming (3e):517

```
fibs ::[Integer]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
take 3 fibs
```

Unlike OCaml, mutual recursion in Haskell does not need to use `let rec`

(because of laziness).

```
isEven :: Int -> Bool
isEven 0 = True
isEven n = isOdd (n - 1)
isOdd :: Int -> Bool
isOdd 0 = False
isOdd n = isEven (n - 1)
```

```
quickSort :: Ord a => [a] -> [a]
quickSort [] = []
quickSort (x:xs) = quickSort [e|e<-xs,e<=x] ++ [x] ++ quickSort [e|e<-xs, e>x]
```

`Ord`

is a type class (interface),
and `[e|e<-xs,e<=x]`

is list comprehension.

Function signatures defined in type class are similar to overloading in other languages.

```
class Eq a where
(==) :: a -> a -> Bool
```

`instance`

of type class is similar to classes implemented interface in other languages.

```
instance Monad Maybe where
return x = Just x
Nothing >>= f = Nothing
Just x >>= f = f x
fail _ = Nothing
```

But what is Monad? Read on.

Monad is like a box. It keeps tracking of some extra content and makes code cleaner (but not necessary clearer).

The Maybe monad chains (`>>=`

) sequences of operations and hides failure handling (extra context) in a monad.

Let’s revisit the definition of Maybe from this perspective:
(`--`

starts a comment in Haskell)

```
instance Monad Maybe where
-- `return` is a function to wrap x as `Just x`.
return x = Just x
-- As soon as one fails, the rest are ignored and the final result is `Nothing`.
Nothing >>= f = Nothing
-- Only apply `f` when x is `Just x`， not `Nothing`.
Just x >>= f = f x
-- Throw a failure.
fail _ = Nothing
```

The type class of Monad is defined as below:

```
class Monad m where
-- core functions of Monad
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
-- other functions
(>>) :: m a -> m b -> m b
m >> k = m >>= \_ -> k -- `\_ -> k` is a lambda
fail :: String -> m a
fail s = error s
```

`fail`

is like `throw`

in other languages.
Haskell uses it to in pattern matching to enable failure.
We do not write them explicitly in code.

`>>`

is a syntax sugar to throw away the result of `m a`

.
Thus `putStr "foo" >== \_ -> putStr "bar"`

can be expressed as
`putStr "foo" >> putStr "bar"`

.

`>>=`

chains tow computations,
passing the result of the first computation to the second computation,
by wrapping the second computation in a function,
and passing the first result as its parameter.

Unlike other languages, in Haskell, `return`

wraps date in a monad.

Let’s revisit the definition of Maybe monad under the perspective of monadic class.

```
instance Monad Maybe where
return :: a -> Maybe a
return x = Just x
>>= :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= f = Nothing
Just x >>= f = f x
fail :: String -> Maybe a
fail _ = Nothing
```

```
helloWorld :: IO ()
helloWorld =
do
putStr "Hello"
putStr " "
putStrLn "world!"
```

Haskell syntax is layout sensitive, in other words, it conforms to offside rule. Although Haskell does support braces and semicolons, this alternative style is rare in the Haskell community.

```
do { putStr "Hello"; putStr " "; putStrLn "world!"; }
```

Within a do notation, `<-`

binds the result to a name.

```
echo :: IO ()
echo =
do
line <- getLine
putStrLn line
```

In fact, do notation is an alternative syntax for monad:

```
putStr "Hello" >> putStr " " >> putStrLn "world!"
echo :: IO ()
echo = getLine >>= putStrLn
```