I came across this question on modeling inheritance in Haskell and it reminded me that I have a little more complicated version of the same problem. I\'ll adopt the example from
Perhaps it's just that this example with colours isn't particularly good, but it seems to me that you shouldn't ever truely need this and it wouldn't actually be good if it worked.
Physical
is indeed perfectly natural the way you propose it: a Monster
, Camera
etc. doesn't have a position by itself, rather position is what you get by combining such a object with some space to live in.
But Coloured
is different, for colour is a property of the thing itself and will probably have quite different meaning for a monster compared to a camera, so unlike Physical
a type class would actually seem reasonable here. If at all – perhaps it would actually be better to simply use monomorphic functions for dealing with the various kinds of colour-ness manually.
Of course, you might be tempted think of it this way: things themselves aren't coloured, but they wear a skin that has colour. I don't think this should be the only way to have colour, but... fair enough, we can obviously provide such a "skin" so uncoloured objects become colourful too:
data ClSkin a = ClSkind { clSkinColour :: Colour
, clSkinned :: a }
instance Coloured (Clsskin a) where
colour = clSkinColour
Now you say it shouldn't matter if you use Physical (ClSkin a)
or ClSkin (Physical a)
. I say it does matter. Again, Physical
is sort-of a combination between an object and the entire space it lives in. Surely, you don't want to colourise that entire space! So really, Physical (ClSkin a)
is the only meaningful variant. Or, alternatively, you might say colour is something that only makes sense for objects in a physical space. Well, then you'd just make the colour an extra field of that data!
data Physical a = Physical a Vec3 Vec3 (Maybe Colour)