Algebraic Data Types for fun and profit

I'm online!

Algebraic Data Types for fun and profit

Algebraic

Data

Type

class DnsRecord {
    String recordType;
    String domainName;
    String cnameAlias;
    IpAddr recordIp;
    int ttl;
}
if(record.recordType.equals("CNAME")) {
    // should not be null
    record.cnameAlias;
} else if(record.recordType.equals("A")) {
    // should not be null
    record.recordIp;
} else {
    // ???
}

Implicit subset of fields

No Exhaustivity check

switch() {
  //...
  case default:
    throw new RuntimeException(
      "This should not happen lol"
    );
}

Sum and Products

Product type

Tuple?

Record?

Oh, right.

POJO

a * b

(Bool * Bool)

2 * 2 = 4

Sum type

Enum

Pending | Accepted | Rejected

Sum type

Status + Bool

3 + 2 = 5

Sum type

  CnameRecord ( ttl, name, alias )
| ARecord     ( ttl, name, ipv4 address )
| AaaaRecord  ( ttl, name, ipv6 address )
| TxtRecord   ( ttl, name, value )

Haskell


data DnsRecord =
    CnameRecord Int String String
  | ARecord Int String IpV4
  | AaaaRecord Int String IpV6
  | TxtRecord Int String String
sealed trait DnsRecord
case class CnameRecord(...)
  extends DnsRecord
case class ARecord(...)
  extends DnsRecord
case class AaaaRecord(...)
  extends DnsRecord
case class TxtRecord(...)
  extends DnsRecord

Javascript

var adt = require('adt');
var DnsRecord = adt.data({
  CnameRecord: { ttl: adt.only(Number), ... },
  ARecord: { ttl: adt.only(Number), ... },
  AaaaRecord: { ttl: adt.only(Number), ... }
});

Let's factor it out

DnsRecord( ttl, name,
    AValue(ipv4)
  | AaaaValue(ipv6)
  | CnameValue(alias)
  | TxtValue(name)

Distributivity

(a * b + a * c)
<=>
a * (b + c)

Commutativity

(a * b) <=> (b * a)
(a + b) <=> (b + a)

Identities

(a * 1) <=> a
(a + 0) <=> a

Unit type

Associativity

(a + b) + c <=> a + (b + c)
(a * b) * c <=> a * (b * c)

Functions

a -> b

ba

c(a * b)

(cb)a

(a, b) -> c

a -> b -> c

#Currying

Do your homework

#intuition

Thanks

devoxxroxx2016

Thanks

http://cltdl.fr/gifs

I'm online!