Reflection:
algebraic data types for mortals
About me
- Mathematics Student at Imperial
- PHP Core developer & documentation maintainer
What are Algebraic Data Types?
Definition
Warning: Software development, Computer Science, and Type Theory don't agree on what stuff means at time
Definition
Definition
Source: Wikipedia: https://en.wikipedia.org/wiki/Algebraic_data_type
Definition
In computer programming, especially functional programming and type theory, an algebraic data type is a kind of composite type, i.e., a type formed by combining other types.
Source: Wikipedia: https://en.wikipedia.org/wiki/Algebraic_data_type
Definition
In computer programming, especially functional programming and type theory, an algebraic data type is a kind of composite type, i.e., a type formed by combining other types.
Two common classes of algebraic types are product types (i.e., tuples and records) and sum types (i.e., tagged or disjoint unions, coproduct types or variant types).
Source: Wikipedia: https://en.wikipedia.org/wiki/Algebraic_data_type
Product types
The popular ADT
Product types
Explanation for mortals
Product types
Explanation for mortals
Product types allow you to have more than one value in a single structure, at the same time.
<?php
class BoolTuple2 {
public bool $boolean1;
public bool $boolean2;
public function __construct(bool $boolean1, bool $boolean2) {
$this->boolean1 = $boolean1;
$this->boolean2 = $boolean2;
}
}
Product type examples
<?php
class BoolTuple2 {
public function __construct(public bool $boolean1, public bool $boolean2) {}
}
Product type examples
<?php
class BoolTuple2 {
public function __construct(public bool $boolean1, public bool $boolean2) {}
}
Product type examples
How many ways can we construct BoolTuple2?
<?php
class BoolTuple2 {
public function __construct(public bool $boolean1, public bool $boolean2) {}
}
Product type examples
How many ways can we construct BoolTuple2?
<?php
$trueTrue = new BoolTuple2(true, true);
$trueFalse = new BoolTuple2(true, false);
$falseTrue = new BoolTuple2(false, true);
$falseFalse = new BoolTuple2(false, false);
<?php
class BoolTuple2 {
public function __construct(public bool $boolean1, public bool $boolean2) {}
}
Product type examples
How many ways can we construct BoolTuple2?
<?php
class Digit {
public int $digit;
public function __construct(int $digit) {
if ($digit < 0 || $digit > 9) {
throw new ValueError('Value must be a digit');
}
$this->digit = $digit;
}
}
class Composite {
public function __construct(public BoolTuple2 $boolTuple2, public Digit $digit) {}
}
Product type examples
<?php
class Digit {
public int $digit;
public function __construct(int $digit) {
if ($digit < 0 || $digit > 9) {
throw new ValueError('Value must be a digit');
}
$this->digit = $digit;
}
}
class Composite {
public function __construct(public BoolTuple2 $boolTuple2, public Digit $digit) {}
}
Product type examples
How many ways can we construct Composite?
<?php
class Digit {
public int $digit;
public function __construct(int $digit) {
if ($digit < 0 || $digit > 9) {
throw new ValueError('Value must be a digit');
}
$this->digit = $digit;
}
}
class Composite {
public function __construct(public BoolTuple2 $boolTuple2, public Digit $digit) {}
}
Product type examples
How many ways can we construct Composite?
<?php
class Digit {
public int $digit;
public function __construct(int $digit) {
if ($digit < 0 || $digit > 9) {
throw new ValueError('Value must be a digit');
}
$this->digit = $digit;
}
}
class Composite {
public function __construct(public BoolTuple2 $boolTuple2, public Digit $digit) {}
}
Product type examples
How many ways can we construct Composite?
<?php
class Digit {
public int $digit;
public function __construct(int $digit) {
if ($digit < 0 || $digit > 9) {
throw new ValueError('Value must be a digit');
}
$this->digit = $digit;
}
}
class Composite {
public function __construct(public BoolTuple2 $boolTuple2, public Digit $digit) {}
}
Product type examples
How many ways can we construct Composite?
<?php
class Digit {
public int $digit;
public function __construct(int $digit) {
if ($digit < 0 || $digit > 9) {
throw new ValueError('Value must be a digit');
}
$this->digit = $digit;
}
}
class Composite {
public function __construct(public BoolTuple2 $boolTuple2, public Digit $digit) {}
}
Product type examples
How many ways can we construct Composite?
Sum types
Also know as Coproduct types
Sum types
Explanation for mortals
Sum types
Explanation for mortals
Sum types are types where your value must be one of a fixed set of options.
Sum type examples
Sum type examples
Enumerations, aka Enums
Sum type examples
Booleans
Enumerations, aka Enums
Sum type examples
Booleans
Our Digit class
Enumerations, aka Enums
Sum type examples
Sequences
Sum type examples
Lists
Sequences
Sum type examples
Lists
Strings
Sequences
Sum type examples
Union types
Sum type examples
Union types
<?php
class BoolOrDigit {
public function __construct(public bool|Digit $boolOrDigit) {}
}
Sum type examples
Union types
<?php
class BoolOrDigit {
public function __construct(public bool|Digit $boolOrDigit) {}
}
How many ways can we construct BoolOrDigit?
Sum type examples
Union types
<?php
class BoolOrDigit {
public function __construct(public bool|Digit $boolOrDigit) {}
}
How many ways can we construct BoolOrDigit?
Sum type examples
Union types
<?php
class BoolOrDigit {
public function __construct(public bool|Digit $boolOrDigit) {}
}
How many ways can we construct BoolOrDigit?
Sum type examples
Union types
<?php
class BoolOrDigit {
public function __construct(public bool|Digit $boolOrDigit) {}
}
How many ways can we construct BoolOrDigit?
Pattern matching
Reason why sum types are๐
Definition
Source: Wikipedia: https://en.wikipedia.org/wiki/Pattern_matching
Definition
In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern.
Source: Wikipedia: https://en.wikipedia.org/wiki/Pattern_matching
Definition
In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern.
Source: Wikipedia: https://en.wikipedia.org/wiki/Pattern_matching
The patterns generally have the form of either sequences or tree structures.
Poor man Pattern matching example
<?php
class Nil {}
class Leaf {
public function __construct(public int $value) {}
}
class Node {
public function __construct(public Tree $left, public Tree $right) {}
}
class Tree {
public function __construct(public Nil|Leaf|Node $val) {}
}
Poor man Pattern matching example
<?php
class Nil {}
class Leaf {
public function __construct(public int $value) {}
}
class Node {
public function __construct(public Tree $left, public Tree $right) {}
}
class Tree {
public function __construct(public Nil|Leaf|Node $val) {}
}
function depth(Tree $tree): int {
$val = $tree->val;
return match ($val::class) {
Nil::class => 0,
Leaf::class => 1,
Node::class => 1 + max(depth($val->left), depth($val->right)),
};
}
Poor man Pattern matching example
<?php
$treeExample = new Tree(new Node(
new Tree(new Leaf(5)),
new Tree(new Node(
new Tree(new Node(
new Tree(new Nil()),
new Tree(new Leaf(2)),
)),
new Tree(new Leaf(6)),
))
));
print depth($treeExample);
Poor man Pattern matching example
<?php
$treeExample = new Tree(new Node(
new Tree(new Leaf(5)),
new Tree(new Node(
new Tree(new Node(
new Tree(new Nil()),
new Tree(new Leaf(2)),
)),
new Tree(new Leaf(6)),
))
));
print depth($treeExample);
5
2
6
Poor man Pattern matching example
<?php
$treeExample = new Tree(new Node(
new Tree(new Leaf(5)),
new Tree(new Node(
new Tree(new Node(
new Tree(new Nil()),
new Tree(new Leaf(2)),
)),
new Tree(new Leaf(6)),
))
));
print depth($treeExample);
5
2
6
4
Output
Poor man Pattern matching example
<?php
$treeExample = new Tree(new Node(
new Tree(new Leaf(5)),
new Tree(new Node(
new Tree(new Node(
new Tree(new Nil()),
new Tree(new Leaf(2)),
)),
new Tree(new Leaf(6)),
))
));
print depth($treeExample);
5
2
6
4
Output
What about Reflection?
What about Reflection?
Well, turns out we don't need it. ๐
Thank you!
Sources and inspiration:
- Wikipedia, Algebraic Data Types
- Wikipedia, Pattern Matching
-
Algebraic Data Types: Things I wish someone had explained about functional programming
Blog post by James Sinclair -
Thinking Functionally in PHP
Book by Larry Garfield
ย
Reflection: algebraic data types for mortals
By girgias
Reflection: algebraic data types for mortals
- 1,076