split shrinking into a separate module
don't strink before simplification

can remove opportunities for simplification, for example in `zipWith f xs xs`.
Fixed matching for FFI nodes
FFI nodes are matched based on the StableName of the foreign function to prevent the pure version being unnecessarily evaluated.
relax overly restrictive class constraint
fix pretty printing for Iterate
debug: pretty printing for simpl-stats
debug: add warning message style
rename prettyAcc -> prettyOpenAcc
substitution: wibbles, add simpl-stats counters
rewrite: updates for changes to substitution module
define a toolkit of operations for working with acc parameterised terms
algebra: updates

- parameterise by acc
- add simpl-stats counters
- for now; disable commutes/associates
shrink: updates

- add class Shrink
- parameterise by acc
- add simpl-stats counters
simplify: updates

- clean up, parameterise by acc
- add simpl-stats counters
fusion rewrite

- faster, cleaner, better documentation
- parameterise by acc
- add simpl-stats counters
- an optional second-pass that explicitly embeds producers into consumers.
add simpl-stats for Generate
fusion: rewrite (again) and vastly improve complexity

The key change is to separate the existential type carrying the change in environment, from the representation of how to generate the array. Previously, aligning the environments of terms so that they could be manipulated resulted in significant additional work converting between the delayed and AST forms.
pretty printing for delayed arrays
fusion/aletD: add TODO
indicate whether any work was done during shrink or simplify

The simplification process can stop as soon as no more changes are made, without needing to compare the new and old expressions via `match`.