Re: [Haskell-cafe] Splitting data and function declarations over multiple files
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 ___
Re: [Haskell-cafe] Splitting data and function declarations over multiple files
Opps, errors, it should be more like: moveBall (Vector2 x y) (Ball ...) = ... movePaddle (Vector2 x y) (Paddle ...) = ... -- selection actions for Ball instance Actor Ball where mkActor this = let pos' = getBallPosition this move' v = mkActor $ moveBall v this in Actor pos' move' -- selection actions for Paddle instance Actor Paddle where mkActor this = let pos' = getPaddlePosition this move' v = mkActor $ movePaddle v this in Actor pos' move' Hmm, I bet some generics, or template haskell could clean up the extra boilerplate associated with this technique. - Job On Thu, Oct 1, 2009 at 11:35 AM, Job Vranish jvran...@gmail.com wrote: 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.comwrote: 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
Re: [Haskell-cafe] Splitting data and function declarations over multiple files
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] Splitting data and function declarations over multiple files
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. But wouldn't it be possible to allow these to be put into multiple files, and let the compiler merge them back into one? A bit like C#'s partial keyword: in file Ball.hs: *partial data Actor = Ball ...* *move (Ball ...) =* in Paddle.hs *partial data Actor = Paddle ...* *move (Paddle ...) =* The compiler would then merge all partial data types and functions into one. As far as no overlap exists in the pattern matches in move, so that the order of the pattern matches does not matter at all, the partial trick should be possible no? Cheers, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting data and function declarations over multiple files
Hi Peter, sounds to me you want to have a look at Open Data Types and Open Functions by Andres Löh and Ralf Hinze: http://people.cs.uu.nl/andres/OpenDatatypes.pdf Cheers, /Niklas On Wed, Sep 30, 2009 at 5:54 PM, 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. But wouldn't it be possible to allow these to be put into multiple files, and let the compiler merge them back into one? A bit like C#'s partial keyword: in file Ball.hs: partial data Actor = Ball ... move (Ball ...) = in Paddle.hs partial data Actor = Paddle ... move (Paddle ...) = The compiler would then merge all partial data types and functions into one. As far as no overlap exists in the pattern matches in move, so that the order of the pattern matches does not matter at all, the partial trick should be possible no? Cheers, Peter ___ 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
Re: [Haskell-cafe] Splitting data and function declarations over multiple files
On Wed, Sep 30, 2009 at 8:54 AM, Peter Verswyvelen bugf...@gmail.comwrote: I guess this is related to the expression problem. Actually, this is exactly 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. Yes, and type classes are the current solution. I think the most elegant solution right now is provided by Data Types a la Carte; see http://www.cse.chalmers.se/~wouter/publications.html But wouldn't it be possible to allow these to be put into multiple files, and let the compiler merge them back into one? A bit like C#'s partial keyword: in file Ball.hs: *partial data Actor = Ball ...* *move (Ball ...) =* in Paddle.hs *partial data Actor = Paddle ...* *move (Paddle ...) =* The compiler would then merge all partial data types and functions into one. As far as no overlap exists in the pattern matches in move, so that the order of the pattern matches does not matter at all, the partial trick should be possible no? Yes, that's true. There's some good reading about this proposal here: http://www.haskell.org/haskellwiki/Extensible_datatypes -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Splitting data and function declarations over multiple files
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