Algebraic design specifies an interface and its laws before selecting concrete data representations. An algebra consists of operations over data types together with rules describing how those operations relate. Deferring representation keeps attention on the concrete problem while the required operations and guarantees are discovered. section 9.1
A practical algebraic-design process proceeds by:
- Choosing a small, concrete domain that exposes the essential operations without distracting details. section 9.1
- Defining primitive operations and compositional combinators as the intended interface. section 9.8
- Writing laws and sample usages that describe how the operations should behave. section 9.1
- Letting the interface, laws, usages, and implementation difficulties iteratively guide the eventual representation. section 9.8
Parser combinators
A parser algebra can begin with a primitive character parser and an execution operation: `char(c): Parser[Char]` and `run(input): Either[ParseError, A]`. Its laws and examples state that `char(c).run(c.toString) == Right(c)`. The algebra then grows through operations such as `string`, choice with `or`, repetition with `listOfN`, and mapping or sequencing. The representation of `Parser` is chosen only after these capabilities and relationships are clear. section 9.1
