Which of the following two designs do you prefer, and why?
Option 1: With the data type
module Point3d
-- origin, coordinates, translateBy...
encode : Point3d -> Value
decoder : Decoder Point3d
generator : Generator Point3d
module Triangle3d
-- vertices, area, rotateAround...
encode : Triangle3d -> Value
decoder : Decoder Triangle3d
generator : Generator Triangle3d
This approach is nice and simple and easy to understand, but introduces a fair bit of coupling. Each module is now tied to a particular data format (JSON), and would depend on third-party packages if this pattern is extended to things like fuzzers.
Option 2: In their own modules
module Geometry.Encode
point3d : Point3d -> Value
triangle3d : Triangle3d -> Value
module Geometry.Decode
point3d : Decoder Point3d
triangle3d : Decoder Triangle3d
module Geometry.Random
point3d : Generator Point3d
triangle3d : Generator Triangle3d
This approach is a bit more complex and the functionality is arguably a bit buried, but it decouples things nicely. These modules could be in their own separate packages with their own dependencies if necessary, which would make it easy to add things like a Geometry.Fuzz module later.
Thoughts?