I'm implementing CSG in a haskell program. When I did that in an OOP lahguage I was inspired by the Composite Patron.
I had an abstract class "Object", some concrete objects (Sphere, plane, etc), and a concrete class "CompositeObject" whith an operator and two pointers to Object.
To implement the CSG tree in that way in Haskell I was thinking in a recursive datatype:
data Shape = Sphere (..some types here..)
| ..other primitive objects..
| Composite Shape Op Shape
Then I define the functions over objects by pattern matching. The problem here, is that all objects must be in this module. All objects are concentrated in a monolith.
I think that is a good idea having a typeclass for objects:
class Shape a where
intersection :: Ray -> a -> [Points]
normal :: Point -> a -> Vector
...
Now I define instances for Sphere, plane, cilinder, etc.
But what about composite objects? How can I create a type constructed from two types of a class, with the class functions depending on the constructors, or something like that?
The usual pattern is to skip the class and just make it data, like this:
data Shape = Shape
{ intersection :: Ray -> [Point]
, normal :: Point -> Vector
}
Then you would have functions like sphere
that took a position and a radius and produced a Shape
; or a composite object that took two Shape
s and did something with them.