liveBook · Manning

Algebraic data type

As explained in Functional Design and Architecture: Examples in Haskell

An algebraic data type is a composite type formed from alternatives, products, or both, with its structure described by type constructors.

An algebraic data type (ADT) defines a domain shape with named alternatives, fields, or both. It makes the allowed states and operations visible in code, so a domain model can become a precise, inspectable representation rather than a collection of loosely related calls. ADTs suit complex structures such as trees, graphs, dictionaries, and business models, and they are a central tool for encoding embedded domain-specific languages (eDSLs). section 5.2 section 5.4

A useful design move is to represent each meaningful domain action as an ADT constructor, then keep a script as pure data. An interpreter can traverse that data and connect it to device calls, logging, state, or other effects. This separates a readable scenario from the recursive, stateful, impure implementation required to run it. section 2.2.2 section 1.3.3

Listing 2.1 Domain-specific language for a smart house
type ThermometerName = String
type BarometerName = String
  
data Language                          #1
  = ReadThermometer ThermometerName
  | ReadBarometer BarometerName
  | ReportTemperature
  | ReportAtmospherePressure
  | ClearData
  
type Script = [Language]               #2
  
script :: Script
script =
  [ ReadThermometer "Garage"           #3
  , ReadThermometer "Near the road"
  , ReadThermometer "House"
  , ReadBarometer "Garage"
  , ReadBarometer "House"
  , ReportTemperature
  , ReportAtmospherePressure
  , ClearData
  ]

The smart-home language models five actions as alternatives in Language, while Script combines them into an ordered scenario. Each constructor states one permitted instruction and its required data. section 2.2.2

Use ADTs to make architectural boundaries explicit:

  • Model a subsystem interface as an ADT plus interpreter when communication must remain functional rather than object-oriented. section 1.3.3
  • Keep constructors private when clients should not depend on representation details; expose smart constructors through an abstract module instead. section 3.2.4
  • Parameterize a template ADT when one domain shape must support different field-type sets, such as domain, SQLite, and PostgreSQL representations. section 12.1.3
  • Use an ADT with continuation fields as the instruction algebra beneath a free-monad language, then provide smart constructors for scripts. section 6.3.1

Keep representation changes behind constructors

A Value type may have BoolValue, IntValue, FloatValue, and StringValue alternatives. If clients pattern-match directly, renaming or adding a constructor breaks their code. Exporting Value while hiding its constructors, and offering functions such as boolValue, stringValue, and intValue, lets the implementation evolve without exposing its internal structure. section 3.2.4

ADTs improve reasoning only when their vocabulary and organization match the domain. A poorly designed eDSL can become restrictive and add accidental complexity; group methods by meaning and scope, separate responsibilities, and preserve the distinction between domain notions and runtime implementation. section 5.4 section 3.1.2

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Develops ADTs through interpreter, encapsulation, free-monad, and HKD designs rather than formal type theory.
Examples
Uses smart-home scripts, abstract Value values, sandwich recipes, and meteor persistence models.
What it assumes
Introduces practical ADT modeling without requiring advanced mathematical theory, then applies continuations and type-level selection in advanced designs.
What you can do after
Build it from scratch as domain models, interpretable eDSLs, opaque abstractions, and parameterized data templates.
How it connects
Connects ADTs with embedded DSLs, interpreters, smart constructors, modules, free monads, and type families.

Also explained in

Compare how 5 books explain algebraic data type →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.