Start working on part 11 of compiler series
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
49cf8e3e08
commit
33cd4f5f68
63
content/blog/11_compiler_polymorphic_data_types.md
Normal file
63
content/blog/11_compiler_polymorphic_data_types.md
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
title: Compiling a Functional Language Using C++, Part 11 - Polymorphic Data Types
|
||||||
|
date: 2020-03-28T20:10:35-07:00
|
||||||
|
draft: true
|
||||||
|
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||||
|
---
|
||||||
|
[In part 10]({{< relref "10_compiler_polymorphism.md" >}}), we managed to get our
|
||||||
|
compiler to accept functions that were polymorphically typed. However, a piece
|
||||||
|
of the puzzle is still missing: while our _functions_ can handle values
|
||||||
|
of different types, the same cannot be said for our _data types_. This means
|
||||||
|
that we cannot construct data structures that can contain arbitrary types.
|
||||||
|
While we can define and use a list of integers, if we want to also have a
|
||||||
|
list of booleans, we must copy all of our constructors and define a new data type.
|
||||||
|
Worse, not only do we have to duplicate the constructors, but also all the functions
|
||||||
|
that operate on the list. As far as our compiler is concerned, a list of
|
||||||
|
integers and a list of booleans are entirely different beasts, and cannot
|
||||||
|
be operated on by the same code.
|
||||||
|
|
||||||
|
To make polymorphic data types possible, we must extend our language (and type
|
||||||
|
system) a little. We will now allow for something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
data List a = { Nil, Cons a List }
|
||||||
|
```
|
||||||
|
|
||||||
|
In the above snippet, we are no longer declaring a single type, but a collection
|
||||||
|
of related types, __parameterized__ by a type `a`. Any type can take the place
|
||||||
|
of `a` to get a list containing that type of element.
|
||||||
|
Then, `List Int` is a type,
|
||||||
|
as is `List Bool` and `List (List Int)`. The constructors in the snippet also
|
||||||
|
get polymorphic types:
|
||||||
|
|
||||||
|
{{< latex >}}
|
||||||
|
\text{Nil} : \forall a \; . \; \text{List} \; a \\
|
||||||
|
\text{Cons} : \forall a \; . \; a \rightarrow \text{List} \; a \rightarrow \text{List} \; a
|
||||||
|
{{< /latex >}}
|
||||||
|
|
||||||
|
When you call `Cons`, the type of the resulting list varies with the type of element
|
||||||
|
you pass in. The empty list `Nil` is a valid list of any type, since, well, it's
|
||||||
|
empty.
|
||||||
|
|
||||||
|
Let's talk about `List` itself, now. I suggest that we ponder the following table:
|
||||||
|
|
||||||
|
\\(\\text{List}\\)|\\(\\text{Cons}\\)
|
||||||
|
----|----
|
||||||
|
\\(\\text{List}\\) is not a type; it must be followed up with arguments, like \\(\\text{List} \\; \\text{Int}\\).|\\(\\text{Cons}\\) is not a list; it must be followed up with arguments, like \\(\\text{Cons} \\; 3 \\; \\text{Nil}\\).
|
||||||
|
\\(\\text{List} \\; \\text{Int}\\) is in its simplest form.|\\(\\text{Cons} \\; 3 \\; \\text{Nil}\\) is in its simplest form.
|
||||||
|
\\(\\text{List} \\; \\text{Int}\\) is a type.|\\(\\text{Cons} \\; 3 \\; \\text{Nil}\\) is a value of type \\(\\text{List} \\; \\text{Int}\\).
|
||||||
|
|
||||||
|
I hope that the similarities are quite striking. I claim that
|
||||||
|
`List` is quite similar to a constructor `Cons`, except that it occurs
|
||||||
|
in a different context: whereas `Cons` is a way to create values,
|
||||||
|
`List` is a way to create types. Indeed, while we call `Cons` a constructor,
|
||||||
|
it's typicall to call `List` a __type constructor__.
|
||||||
|
We know that `Cons` is a function which
|
||||||
|
assigns to values (like `3` and `Nil`) other values (like `Cons 3 Nil`, or `[3]` for
|
||||||
|
short). In a similar manner, `List` can be thought of as a function
|
||||||
|
that assigns to types (like `Int`) other types (like `List Int`). We can
|
||||||
|
even claim that it has a type:
|
||||||
|
|
||||||
|
{{< latex >}}
|
||||||
|
\text{List} : \text{Type} \rightarrow \text{Type}
|
||||||
|
{{< /latex >}}
|
Loading…
Reference in New Issue
Block a user