Lecture 21-1
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
-
data BigThings a b c d = BigThings a b c d derive Show
-
middleTwo :: BigThings a b c d -> (b, c) middleTwo (BigThings _ x y _) = (x, y)
-
data Example = One Int | Two Float isOne :: Example -> Bool isOne x = case x of One _ -> True _ -> False