Skip to content
UoL CS Notes

Lecture 21-1

COMP105 Lectures

Parameterised Custom Types

Type Variables in Custom Types

We can use type variables in custom types:

data Point a = Point a a

Here we say we are making a new type where the constructor point is made of type a.

> :t Point (1::Int) (2::Int)
Point Int

We can also use multiple variable in the same type.

data Things a b c = Things a b c deriving (Show)
> Things "string" 1 True
Things "string" 1 True

When using a type that includes type variables the resultant type has its own type based on the types of data it was given. This links to how you can’t compare lists of two different types.

We can write functions using these types:

first_thing (Things x _ _) = x
> first_thing (Things 1 2 3)
1
> :t first_thing
first_thing :: Things a b c -> a

case Expressions

case expressions allow you to do pattern matching inside of functions.

data Example = One Int | Two Float

f :: Example -> Int
f x = case x of One a -> a
                Two b -> 0
> f (One 3)
3
> f (Two 4.0)
0

Example

Using case you can write functions that formerly would have been implemented in pattern matching:

f [] = 0 
f (x:xs) = 1 + f xs

f' list = case list of  []      -> 0
                        (x:xs)  -> 1 + f xs

Syntax

The syntax for a case expression is:

case [expression] of    [pattern 1] -> [expression]
                        [pattern 2] -> [expression]
                        ...
                        [pattern k] -> [expression]

All patterns should be on the same column in order for Haskell to process the expression correctly.

Additionally you can use the _ as a catch all at the end of the expression.

You can put them all on one line using the following syntax:

case x of {One a -> a; Two b -> 0}

Finally case is an expression so you can treat its result as a value:

> (case 1 of 1 -> 1) + (case 2 of 2 -> 1)
2

Exercises

  1.  data BigThings a b c d = BigThings a b c d derive Show
    
  2.  middleTwo :: BigThings a b c d -> (b, c)
     middleTwo (BigThings _ x y _) = (x, y)
    
  3.  data Example = One Int | Two Float
     isOne :: Example -> Bool
     isOne x = case x of One _ -> True
                         _     -> False