Part 19

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 have reached the end of this section! Continue to the next section:

You can check your current points from the blue blob in the bottom-right corner of the page.