Algebraic Data Types (ADTs)

Agenda

  • Motivation
  • What are ADTs?
  • Why are they useful?
  • Generic programming with ADTs

Motivation

"Functional Programming is writing programs with (pure) functions and (immutable) data"

~ Probably someone from the internet

Functions

Data

+

Focus of this talk

What are ADTs?

ADTs are product types, sum types and compositions of those

Product types

Often also called records or (named) tuples

Combine values with "AND"

Sum types

Often also called coproduct or disjoint unions

Combine values with "OR"

*

* Scala's way of writing ADTs is truly the worst of any FP language -_-'

Compositions

Mix and nest as you wish

Why are they useful?

1. "Exhaustiveness Checking"

Compiler is helping us out:

 => Incredibly helpful for easy and safe refactorings/changes

Why are they useful?

2. Help with partiality when modelling application state

Can have many inconsistent states!

Using an ADT the compiler will force you to handle partiality/errors:

Why are they useful?

2.1. Limited amount of possible states

 Possible states: 2 * 2 * 2

 Possible states: 1 + 1 + 1 + (2 * 2)

 => This shows where sum and product in the names come from

 => Great for finite state machines

Why are they useful?

3. Expressive data types are a design tool and documentation

Can you guess what program this is by just looking at the data model for it?

Why are they useful?

4. Keeping data separate from implementation details helps with reusability of your domain model

This brings us to...

Generic programming with ADTs

A lot of things we do with data involves (de)serialization. Writing the code for this by hand is tedious and error-prone.

Typeclasses help to do this without reflection, but normally require to still write the logic for each new type

Generic programming with ADTs

Serializing to json with circe:

Nobody has time for this...

Generic programming with ADTs

Circe can derive the typeclass instances for sum and product types:

This is still type-safe and fast (no runtime reflection) and can reduce the boilerplate to zero (for automatic derivation)!

Generic programming with ADTs

If you want the same for your own code you have to either:

  1. Write your own derivation macro (not recommended)
  2. Use shapeless
    ​  - powerful
      - kinda slow
      - hard to understand
  3. Use magnolia
      - doesn't support higher-kinded types
      - faster than shapeless
      - easier to get started

Generic programming with ADTs

Magnolia example:

+

Generic programming with ADTs

Magnolia has decent error messages if a type has no typeclass instance

E.g. No typeclass instance for "LocalDate" type

Inspirations for this talk

Algebraic Data Types (ADTs) in Scala

By Felix Bruckmeier

Algebraic Data Types (ADTs) in Scala

  • 157