Along the projection/co-algebra lines (I actually didn't know that's what they were called until today :) yay for learning new things!)
How about something like this: -- Define "prototypes" for your class of actions here data Actor = Actor {pos::Vector2 Float, move::Vector2 Float -> Actor} -- simple class that selects your actions based on type class ActorClass a where mkActor :: a -> Actor -- object types data Ball = Ball ... -- stuff data Paddle = Paddle ... -- stuff data Wall = Wall ... -- suff -- Functions for working with objects getBallPosition (Ball ...) = ... getPaddlePosition (Paddle ...) = ... moveBall (Ball ...) = ... movePaddle (Ball ...) = ... -- selection actions for Ball instance Actor Ball where mkActor this = let pos' = getBallPosition this move' v = moveBall this in Actor pos' move' -- selection actions for Paddle instance Actor Paddle where mkActor this = let pos' = getPaddlePosition this move' v = movePaddle this in Actor pos' move' Base off a technique I ran across here: http://www.mail-archive.com/hask...@haskell.org/msg04513.html Also, a useful wikipage for doing OO things in haskell: http://www.haskell.org/haskellwiki/OOP_vs_type_classes - Job On Thu, Oct 1, 2009 at 4:45 AM, Peter Verswyvelen <bugf...@gmail.com> wrote: > I'm not sure if I understand what you mean with this co-algebraic approach, > but I guess you mean that functions - like move - don't work directly on any > datatype; you need to provide other functions that give access to the data. > But that's basically what type classes do no? And that's also related to my > earlier post of "strong duck typing" in Haskell. > At least also in C#, that's the way I usually write code that works on any > type, just make an interface or pass in a delegate. I also know that my OO > background keeps pushing me in the wrong direction when it comes to Haskell > ;-) > > The collision handling approach is always interesting :) In OO this is > usually solved using multi-methods or visitors: > http://en.wikipedia.org/wiki/Multiple_dispatch. What I usually did in old > games of mine to handle collisions is not look at the type, but at the > "collision specific features" of a type (which are again functions that > extract information from the object), and that is most likely again the > co-algebraic approach? > > On Wed, Sep 30, 2009 at 9:15 PM, Luke Palmer <lrpal...@gmail.com> wrote: > >> On Wed, Sep 30, 2009 at 9:54 AM, Peter Verswyvelen <bugf...@gmail.com> >> wrote: >> > I guess this is related to the expression problem. >> > Suppose I have a datatype >> > data Actor = Ball ... | Paddle ... | Wall ... >> > and a function >> > move (Ball ...) = >> > move (Paddle ...) = >> > move (Wall ...) = >> > in Haskell one must put Actor and move into a single file. >> > This is rather cumbersome if you work with multiple people or want to >> keep >> > the files small and readable. >> > Surely it is possible to use type classes, existentials, etc to split >> the >> > data type into multiple ones, but that's already advanced stuff in a >> sense. >> >> You can do it without type classes and existentials. The >> functionality you want is already supported by Haskell, you just have >> to let go of your syntactical expectations. The trick is that you >> should rewrite your data type not as an algebra (a set of >> constructors), but as a coalgebra (a set of projections). >> >> Let's say your two open functions are: >> >> move :: Actor -> Actor >> isAlive :: Actor -> Bool >> >> This gives rise to the definition of an Actor type: >> >> data Actor = Actor { move :: Actor, isAlive :: Bool } >> >> And then the alternatives of your open data type are just values of type >> Actor: >> >> ball :: Vector -> Vector -> Actor >> ball pos vel = Actor { >> move = ball (pos + vel) vel, >> isAlive = True >> } >> >> etc. >> >> This trick works well until you get to the encoding of functions that >> pattern match on multiple Actors at the same time. As far as I can >> tell, that cannot be encoded in this style in any reasonable way. >> Such functions must be rephrased in a coalgebraic style; i.e. instead >> of asking about constructors, using projection functions it knows are >> available. >> >> So for example instead of implementing "collide" by asking about >> pairs, add functions which report a shape function and a normal, or >> whatever your collide algorithm needs from shapes. >> >> You would probably end up having to do this anyway even with your >> proposed extension, because watch: >> >> partial data Actor = Ball ... >> >> collide (Ball ...) (Ball ...) = ... >> collide (Ball ...) x = ... >> >> We don't know about any other constructors, so the second line has to >> contain a pattern-free x. So you would have to use projection >> functions to get any information about it, exactly as you would when >> you're writing in the coalgebraic style. >> >> So, Yes! Haskell can do that! >> >> Luke >> > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe