Suppose I have an object which has a point denoting it's location and shape.
type Point = (Double, Double)
data Object =
Object { location :: Point
, shape :: Shape }
where a shape might be like
data Shape
= Circle { radius :: Double }
| Rectangle { height :: Double, width :: Double }
Suppose I have a function which can draw objects.
draw :: [Object] -> IO ()
So far here are no problems.
Now, suppose I want objects to move. So objects should have a velocity.
type Velocity = (Double, Double)
data Object =
Object { location :: (Double, Double)
, shape :: Shape
, velocity :: Velocity }
type Time = Double
move :: Time -> Object -> Object
moveAll :: Time -> [Object] -> [Object]
The problem is that I need a velocity field to move objects, but I don't need it to draw them.
I think that allowing draw function to know about object's velocity breaks
abstraction. Am I right?
How to combine previous object definition with extra velocity field in order to move objects?
- To use tuples like
(Velocity, Object)? - To wrap both into new data type? If so, then how to call that data type?
Any suggestions are appreciated.
MovableObjectthat containsObjectplus its velocity. Most of the time it's better to have a dedicated, named data type rather than using tuples. Whether or not making velocity available todrawdepends on what exactly you want to draw. For example if you decide to draw arrows representing velocity, it would be appropriate.lensprovides tools to interact with deeply nested data structures.