Product type #
A product type can be viewed as a simplistic class, and its values as simplistic objects.
in Haskell #
Declaration #
Syntax. A product type can be declared as
data <product type name> = <constructor> <type 1> ... <type n>where the product type name and the constructor start with a capital letter.
Example. The following declaration defines a product type
Card:-- a playing card, represented as as suit and a rank data Card = CardC Suit IntThe constructor for this type is
CardC.
Usage #
The constructor lets us create expressions with this type (similarly to a constructor in Java).
Example. The expression
CardC Spades 8has type
Card.
Naming conventions #
Syntax. The name of a constructor is arbitrary.
Example. the type
Cardcan equivalently be declareddata Card = MyConstructor Suit Int
Warning. The name of a product type and its constructor can be identical (as in Java). This is a widely adopted practice in Haskell.
Example.
data Card = Card Suit Int
Convention. In this course, for didactic reasons, we will use different names for a product type and its constructor.
Pattern matching #
A constructor can be used to create a complex pattern.
Example.
data Card = CardC Suit Int getRank :: Card -> Int getRank (CardC _ r) = r isSpades :: Card -> Bool isSpades (CardC Spades _) = True isSpades _ = False
Consider the following program:
data Card = CardC Suit Int
aFunction :: [Card] -> [Int]
aFunction [] = []
aFunction (CardC Diamonds r : cs) = r : aFunction cs
aFunction (_ : cs) = aFunction cs
- What does the following expression evaluate to?
aFunction
[
CardC Diamonds 6,
CardC Hearts 4,
CardC Spades 6,
CardC Diamonds 10
]
- More generally, what does the function
aFunctiondo?
[6,10]
- It maps a list of cards to the ranks of diamond cards that it contains.
Same two questions as above, for the function anotherFunction below (recall the higher-order functions filter and map seen earlier).
data Card = CardC Suit Int
anotherFunction :: [Card] -> [Int]
anotherFunction = map (\(CardC _ r) -> r) . filter (\(CardC s _) -> s == Diamonds)
It is equivalent to the function of the previous exercise.
Record-like notation #
Syntax. Haskell provides an alternative notation for a product type, using attribute names.
For instance:data Card = CardC { suit :: Suit, rank :: Int }This is very similar to structures in C or records in Java.
Usage #
An attribute name can be used as regular function to access its value.
Example.
data Card = CardC { suit :: Suit, rank :: Int } isRed :: Card -> Bool isRed c = suit c == Diamonds || suit c == Hearts
We can create an expression with this type as follows:
Example. The expression
CardC { suit = Spades, rank = 8 }has type
Card.