Data Types with Parameters
The Maybe
“data type” has a definition like this:
data Maybe a = Nothing | Just a
This means that putting in types gives out different data types:
data Maybe Double = Nothing | Just Double
data Maybe String = Nothing | Just String
(Warning: these are not legal Haskell; to make them legal, make the
left side one word like Maybe_Double
.)
The Maybe type is built in, but anyone can make a data type that has a similar unknown parameter.
-
Make three different instances of
Triple Int
, one for each possibility.data Triple a = Never | Unlikely a | Surely a
-
It is allowed to have types on the right that never appear on the left. Those are always present; only the
a
type can vary. (See Types vs Constructors below.)data ProbablyL a = Never | ProbablyR Double a
Make two examples of
ProbablyL String
. -
Write your own data definition and examples for a type
Twin
so that all of the following work:-
Both of these variables could be instances of
Twin Double
.a1 = Twin 1.5 4.5 a2 = NotPresent
-
Make it possible for these to be instances of
Twin String
:b1 = Twin “Forward” “Backward” b2 = NotPresent
-
Make it not possible to make
Twin 0.5 "half"
.
-
Types vs Constructors
The standard Maybe
data definition has a “pun” - it uses the same
word for two different meanings. The word Maybe
on the left is part
of a type, while the Maybe
on the right is called a constructor.
data Maybe a = Nothing | Maybe a
Changing the names will help clarify:
data MaybeL a = Nothing | MaybeR a
Now write a function fixer
that takes in a Maybe Int and puts out an Int,
giving 0 in the case of Nothing. Notice which version of Maybe is used
in the type signature and which is used to access the value.
fixer :: MaybeL Int -> Int
fixer (MaybeR x) = x
fixer Nothing = 0
The pun is not very confusing when the left and right sides have the same number of arguments, but when they don’t watch out!
Types vs Constructors II
Consider the example type “Concern”, which takes in a single type variable. The idea is that whatever the “concern” is, it will be accompanied by an int indicating how big of a concern.
data ConcernL a = ConcernR Int a
deriving (Show)
Exercises:
-
A String concern has the string “leaky ceiling” and the value for the level of concern is 80.
- Create a variable holding this example.
- Write the type signature for that variable.
-
A function is supposed to take a list of concerns and output a list of those whose level of concern is at least 50.
- Write the type signature for this function.
- Write the function.
- Make up a few more examples like the one above so you can test your function.