Skip to content

Instantly share code, notes, and snippets.

@d6y
Created November 2, 2016 08:57
Show Gist options
  • Save d6y/836b4ef1696847297fb161c632a1d41c to your computer and use it in GitHub Desktop.
Save d6y/836b4ef1696847297fb161c632a1d41c to your computer and use it in GitHub Desktop.
Notes from Functional Brighton LYAHFGG Part II

Types and Typeclasses

NB: :{ and :} to paste blocks into GHCi.

Types

  • Every expression has a type known at compile time
  • Examine a type with :t
  • Common types: Int, Integer, Float, Double, Bool, Char
  • functions have types e.g., addThree

Type variables

  • Type variables :t head or :f fst
  • head :: [a] -> a - head is a function that takes a list of as, and evaluates to an a. There is no constraint on what a can be, so we know we can put anything in a list, but it has to be the same anything.

Typeclasses

  • Type classes: behaviour or interface.
  • E.g., :t (==)
  • Anything before => is a class constraint
  • Eq (for = and /=)
  • Ord e.g., :t (>) ...
  • We make our own typeclasses in Chapter 8
  • but... https://www.schoolofhaskell.com/user/garrett.mitchener/Type%20classes gives an idea of what that is like: the class syntax defines the "interface", and then implementations are provided for specific types, such as Eq for Int.

Syntax in Functions

Multiple bodies

  • When defining functions, you can define separate function bodies for different patterns
  • First one to match wins
  • e.g., lucky 7 example
  • Non-exhaustive patterns produce runtime errors

Lists

  • List pattern matching: [1,2,3] vs 1 : 2 : 3 : []
  • Example our own version of head, perhaps using error
  • Example of tell to describe a list.
  • "as patterns (@), the example being the first letter of allis x inall@(x:xs)`

Guards

E.g.,

max' a b 
  | a > b     = a
  | otherwise = b

We saw that otherwise is defined as True!

Where

cylinder' r h =
  sideArea + 2 * topArea
  where  
    sideArea = 2 * pi * r * h
    topArea  = pi * r ^ 2  

Syntax only used in defining functions. Whereas...

Let

Let is an expression so can be used anywhere you need an expressions. The syntax is let...in. Examples:

[ let square x = x * x in ((square 1), (square 4)) ]

...produces [ (1,16) ].

cylinder r h =
  let sideArea = 2 * pi * r * h
      topArea  = pi * r ^ 2
  in  sideArea + 2 * topArea

Let can also be used without an in in for comprehensions:

{- revisit when we get to do notation -}
[ square x | x <- [1..3], let square x = x*x ]

Case Expression

For example (spoiler for exercise below!):

safetail xs = case null xs of 
    True  -> []
    False -> tail xs

Can be used anywhere you need an expression.


Exercises

From Noel:

From Programming in Haskell (Hutton), section 4.8:

Consider a function

safetail :: [a] -> [a]

that behaves as the library funtion tail, except that safe tail maps the empty list to itself, whereas tail produces an error in this case.

Define safetail using:

  • (a) a conditional expression
  • (b) guard equations
  • (c) pattern matching

Hint: make use of the library function null.

Exercise we didn't do

Define a function contains that returns True if the value is in the list. E.g.,

contains 6 [1,2,3] -- False!
contains "cat" ["dog", "cat"] -- True!
contains True [False, False, True] -- True!

But write the type signature first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment