<div dir="ltr"><div>Update: I may have gotten existential types to work.</div><div><br></div><div>I'm think of it like this: there's a type Object, which can be unwrapped into different things depending on the type of the existential data.</div><div><br></div><div>data Object = forall s. { common :: Int, custom: s }</div><div><br></div><div><br></div><div>In purescript you define two types:</div><div><br></div><div>import Data.Exists<br></div><div><br></div><div>type ObjectInner s = ObjectInner { common :: Int, custom: s }</div><div><br></div><div>type Object = Exists ObjectInner</div><div><br></div><div>And then you can only access the innards of Object through the runExists and mkExists functions. <br></div><div><br></div><div>I realized that I could think of the situation in a sort-of object oriented way. I've got data, and an interface. I can define the interface as fields with function values.</div><div><br></div><div>type ObjectInner s = ObjectInner { doSomething :: ObjectInner s -> IO (), fetchSomething :: ObjectInner s -> Int, ... }</div><div><br></div><div>My whole application has a single list (or in Purescript, Array) of Object values:</div><div><br></div><div>bigPicture :: Array Object</div><div><br></div><div>I can define functions that use runExists to access the interface of any given Object. My understanding is that the point of Existential types is that the custom type is not supposed to escape its scope. In this method, it seems that both the data and the functions for operating on it are wrapped inside Object.</div><div><br></div><div>I think this is working for me. Needs a little more work.<br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 23, 2018 at 10:14 PM, Dennis Raddle <span dir="ltr"><<a href="mailto:dennis.raddle@gmail.com" target="_blank">dennis.raddle@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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><span class="HOEnZb"><font color="#888888"><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></font></span></div>
</blockquote></div><br></div>