1Shapes, using Modular Data Abstraction
2======================================
3'Shape' is a theory.
4The constructors for this theory are cube, box, ...
5Plus we need 'make_shape'.
6
7I assume Shape is also a type, and that
8    move off (sh :: Shape) = ...
9is an efficient way to require the argument to be a shape.
10
11To define Shape, we construct a branded Theory that specifies the
12operations on a Shape. Pseudocode:
13    def Shape = Theory T {
14        distance Vec3 T -> Num,
15        colour Vec3 T -> Vec3,
16        bounds T -> BBox,
17        is_2d T -> Bool,
18        is_3d T -> Bool,
19    }
20
21In constrast, here is a monoid theory:
22    def Monoid = Theory T {
23        op T T -> T,
24        zero -> T,
25    }
26
27To access the properties of a Shape sh, use
28    Shape.bbox sh
29    Shape.distance [x,y,z] sh
30
31What's the equivalent of make_shape? Syntactically, maybe something like
32    make Shape {
33        distance ...
34        colour ...
35        bounds ...
36        is_2d ...
37        is_3d ...
38    }
39
40By contrast, 'make Monoid' doesn't make sense due to the binary operator.
41Making a single instance of a Theory is legal if all of the operations
42exactly one instance as an argument, then you have a single-dispatch,
43OOP-class-like schema.
44
45Here's another attempt: make_shape is a Shape algebra whose constructor
46maps a record to a Shape instance.
47