Lecture 1.0 — 2016-08-30

Introduction

This lecture is written in literate Haskell; you can download the raw source.

After the usual administrivia and introductions, we talked briefly about craft before diving in to Haskell. We heard the following quote:

To understand craftsmanship, we must ask not only “What has been made?” and “How has this been made?” but also “Who made this and why?” Craftsmanship is a relationship between the maker and the process of creation. It is not simply a set of skills one acquires, like the ability to read or drive a car. More than anything, craftsmanship is a matter of attitude: why we choose to devote time to such a demanding endeavor, why we choose to make a certain object of a certain appearance, and how we go about it.
—Peter Korn, Woodworking Basics: Mastering the Essentials of Craftsmanship

Then we finally got started. We wrote a simple arithmetic function:

mean :: Int -> Int -> Int
mean x y = (x + y) `div` 2

…and after figuring out how to use ghci to test our program, we wrote some more interesting, recursive functions:

fact :: Int -> Int
fact 0 = 1
fact n = n * (fact (n - 1))

fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

We defined an accumulator-passing version of fib:

fib' :: Int -> Int
fib' n = fibAux 1 1 n
  where
    fibAux :: Int -> Int -> Int -> Int
    fibAux f1 f2 0 = f1
    fibAux f1 f2 n = fibAux f2 (f1 + f2) (n-1)

And we saw how important type annotations are to getting good error messages. (Try removing the type annotation on fibAux and forgeting to apply fibAux in the third case.

Then we defined our first datatype, representing the days of the week. (In class, I defined the first day to be Monday, but let’s be faithful to the true week here.)

data Day =
    Sunday
  | Monday
  | Tuesday
  | Wednesday
  | Thursday
  | Friday
  | Saturday

We defined a simple function, isWeekday, using _ to mean “all other cases”.

isWeekday' :: Day -> Bool
isWeekday' Saturday = False
isWeekday' Sunday = False
isWeekday' _ = True

Finally, we saw that the Bool type is no different from Day; we could have written:

data Bool = False | True

In fact, somewhere in Haskell’s default definitions—a/k/a the Prelude—booleans are defined exactly this way.