Question

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?

Was it helpful?

Solution

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 Shapes and did something with them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top