There are a few main classes involved here:
Configuration options to control how prettyprinting occurs, passed recursively into each prettyprinting callsite.
Helpers to help inject behavior into the generated code without having any circular dependencies
Helpers to help inject behavior into the generated code without having any circular dependencies
A typeclass necessary to prettyprint something.
A typeclass you define to prettyprint values of type A
Prettyprint a strongly-typed value, falling back to toString if you don't know what to do with it.
Prettyprint a strongly-typed value, falling back to toString if you don't know what to do with it. Generally used for human-facing output