Summary of Algebraic Datatypes
Algebraic Datatypes: Summary
- Types are defined like this
data TypeName = ConstructorName FieldType FieldType2 | AnotherConstructor FieldType3 | OneMoreCons
- … or like this if we’re using type variables
data TypeName variable = Cons1 variable Type1 | Cons2 Type2 variable
- You can have one or more constructors
- Each constructor can have zero or more fields
- Constructors start with upper case, type variables with lower case
- Values are handled with pattern matching:
foo (ConstructorName a b) = a+b
foo (AnotherConstructor _) = 0
foo OneMoreCons = 7
- Constructors are just functions:
ConstructorName :: FieldType -> FieldType2 -> TypeName
Cons1 :: a -> Type1 -> TypeName a
- You can also define datatypes using record syntax:
data TypeName = Constructor { field1 :: Field1Type, field2 :: Field2Type }
This gives you accessor functions like field1 :: TypeName -> Field1Type
for free.
Sidenote: Other Ways of Defining Types
In addition to the data
keyword, there are two additional ways of defining types in Haskell.
The newtype
keyword works like data
, but you can only have a single constructor with a single field. It’s sometimes wise to use newtype
for performance resons, but we’ll get back to those in part 2.
The type
keyword introduces a type alias. Type aliases don’t affect type checking, they just offer a shorthand for writing types. For example the familiar String
type is an alias for [Char]
:
type String = [Char]
This means that whenever the compiler reads String
, it just immediately replaces it with [Char]
. Type aliases seem useful, but they can easily make reading type errors harder.
Exercises
All exercises can be found in Set5a and Set5b. Please pay attention in the title of the exercise in which file the exercises of this section can be found.
Exercises from 5a:
You can check your current points from the blue blob in the bottom-right corner of the page.