<div dir="ltr"><div>I'm working on an application for animating words, images, and shapes. I'm actually doing it in Purescript and it will become part of a math game that runs in the browser, but I'm asking my question on the Haskell list because the issues seem central to a functional/pure paradigm.</div><div><br></div><div>Let's say that the things being animated are "objects." Objects could include photos, text, shapes, lines, etc. They can have fixed positions, colors, and other attributes, or their attributes can change over time.</div><div><br></div><div>How do I compute attributes that change over time? In some cases, a function with a single argument, the current time, would suffice. I might want state, though -- perhaps an object's movement is pseudorandom and needs to refer to a seed and past position state. <br></div><div><br></div><div>Objects might even need to observe each other's state. For instance, imagine we have two words, W1 and W2, and they move according to some stateful algorithm. Meanwhile we want to draw a line connecting their centers, so we need a line object L that can read the centers of W1 and W2.</div><div><br></div><div>How do I represent the state of W1, W2, and L? I could define a general Object data type: (here there are no fields mentioned)<br></div><div><br></div><div><span style="font-family:monospace,monospace">data Object = W1  | W2  | L </span><br></div><div><br></div><div>I will need state and the ability to customize the drawing and positioning functions, so to flesh out the fields of, say , W1.</div><div><br></div><div><span style="font-family:monospace,monospace">type St = StateT WholeScene IO</span><br></div><div><br></div><div><span style="font-family:monospace,monospace">data Object = W1 { leftEdge        :: Int</span></div><div><span style="font-family:monospace,monospace">                 , rightEdge       :: Int</span></div><div><span style="font-family:monospace,monospace">                 , topEdge         :: Int<br></span></div><div><span style="font-family:monospace,monospace">                 , bottomEdge      :: Int</span></div><div><span style="font-family:monospace,monospace">                 , computePosition :: W1 -> Time -> St W1</span></div><div><span style="font-family:monospace,monospace">                 , draw            :: W1 -> St ()</span></div><div><span style="font-family:monospace,monospace">                 ,  ... other state ...<br></span></div><div><span style="font-family:monospace,monospace">                 }<br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">Okay, so now I could define W2, which will be different in some ways, perhaps needing different state. But it will look a lot alike. It might have the same edge fields.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">In fact, all my objects will have similar position, color, etc. attributes. I certainly don't want to reinvent the wheel for everything.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">I also want objects to be able to read each other's state. Consider a basic positioning task: some object Obj1 keeps its left edge 100 pixels to the right of some other object's right edge. So the Obj1 function for computing position needs access to the other objects.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">Also consider that all these objects need to be put into a list together, to hold the state of the entire scene. They need to be members of the same class, and have a way to look each other up.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">One way to do this is have a single Object type with numerous constructors, and define similar functions on every constructor type (say, a function for accessing or setting the left edge). <br></span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">I also thought about having an Object be an existential type, and the fields that are custom to one object will be the existentially defined data. I actually implemented this in Purescript, but it got out of hand, probably due to my own weakness of understanding how existential types work.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">Any ideas?</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">D<br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><br></div><div><br></div><div><br></div></div>