> Perimeter doesn't make sense for Sphere or Cylinder. So we could define a > type class for objects that have perimeter and make an instance of it only > for Circle (data Circle = Circle Position Radius). Make sense. But these > three functions above have desired behaviour. If user has a list of objects > like [Sphere, Circle, Circle, Cylinder] he would like to calculate > perimeters of each object using map perimerer list (in this case we also > have to modify Geometry data type). > So we could make instances of "perimeter" type class for all objects and > return zero in case if perimeter doesn't make sense. > Same as previous version but with typeclasses and with additional > constructors (constructors for each type of object + constructors in > Geometry data). Looks a bit overcomplicated. > Any reasons to use type classes in this case? Maybe there is something I'm > missing? >
If you're talking about a single datatype with multiple constructors, then the function 'perimeter :: Geometry -> Maybe Double' makes sense. If you're talking about multiple datatypes, then you probably want to go type class route. data Sphere = Sphere ... data Circle = Circle ... class Perimeter a where perimeter :: a -> Double instance Perimeter Circle where perimeter (Circle ...) = ... -- No instance for Sphere class Volume a where volume :: a -> Double instance Volume Sphere where volume (Sphere ...) = ... -- No instance for Circle You have to decide whether (1) a datatype Geometry makes sense or (2) a datatype per geometric entity is better. One advantage to #1 is that writing functions over the datatype is easy. One advantage to #2 is that you have fewer (partial) 'Maybe' functions. This is also related to the "expression problem," a Googleable term. As for having a list of objects, you can do it with either approach. The second approach may require existential types. Regards, Sean
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe