Data Declarations
With the keyword
Data
, we can define new types rather than just synonyms for already existing ones. Types declared with data
are called algebraic, referencing "sum" and "product". In data types, "sum" means alteration (A | B
, meaning A
or B
but not both), and "product" means combination (A B
, meaning A
and B
together).For example, we can create a type that represents a card suit:
data Suit = Hearts
| Diamonds
| Spades
| Clubs
Suit
is the type constructor in this definition, and the values (Hearts
, Diamonds
, Spades
or Clubs
) are data constructors. It states that the new type Suit
can have one of the four values (the |
symbol stands for "or"). This means that Suit
is a sum type, which is any type that has multiple possible representations. Another example of a sum type would be Bool
which can be either True
or False:
data Bool = True | False
Data constructors can have zero or more arguments.
Hearts | Diamonds
and True | False
are examples of data constructors that have zero arguments - nullary data constructors. Likewise, type constructors can have zero or more arguments. Suit
and Bool
are examples of nullary type constructors.Let's take a look at some type- and data- constructors that have more than zero arguments. Here is an example of an error type from the cardano-node repository:
data ConfigError =
ConfigErrorFileNotFound FilePath
| ConfigErrorNoEKG
deriving Show
ConfigError
is a nullary type constructor, and its data constructors are ConfigErrorFileNotFound FilePath
, and ConfigErrorNoEKG
. ConfigErrorFileNotFound FilePath
is a unary data constructor meaning that it actually holds some data, in this case of type FilePath
. Nullary type constructors we have seen so far contain no data aside from their names.Both the type name and its constructors must begin with a capital letter, and constructors must be unique to that type, i.e. the same constructor cannot be defined in more than one type. Once a new type is defined, it can be used in functions just like any other data type in Haskell. To illustrate, a very simple function to get the card suit in a string format using pattern matching would be:
suitStr :: Suit -> String
suitStr Hearts = "... of hearts."
suitStr Diamonds = "... of diamonds."
suitStr Spades = "... of spades."
suitStr Clubs = "... of clubs."
ghci> suitStr Hearts
"... of hearts."
Last modified 3mo ago