How to model this in haskell, get rid of my OO thinking?
Hi, I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode. In C++, I would do (simplified): class ScreenObject { float x,y; void move(dx,dy){x+=dx;y+=dy;} }; class Spaceship : public ScreenObject { void shoot(){...} }; class Rocket : public ScreenObject { void explode(){...} }; But what would I do in haskell? Ok, I can define a typeclass "ScreenObjectType" that has a move function (taking an object, retuning an moved object). But I do not want to implement "move" for both Spaceship and Rocket. Can I somehow give a default implementation for move that works on any datatype having an "x" and "y" element? Or what would I do? Can I somehow define a "base datatype" holding a x and y member form which Spaceship and Rocket derive? I feel like I am thinking to much OOP here. But the point is, I guess, that I want to avoid code duplication! So I guess, it comes down to the questions: How would you model the scenario described above in haskell? Thanks! Nathan
On 05/17/10 23:21, haskell@lonely-star.org wrote:
So I guess, it comes down to the questions: How would you model the scenario described above in haskell?
how about, data Position = Position { positionX :: Float, positionY :: Float } move :: Position -> (Float, Float) -> Position data Spaceship = Spaceship Position ...other data members... data Rocket = Rocket Position ...other data members... (or perhaps not separate data-types but rather data SpaceThing = Spaceship { spacePosition :: Position, ...other data members...} | Rocket { spacePosition :: Position, ...other data members...} ... -- this latter has advantages and disadvantages regarding code reuse and code reliability. Experiment! -Isaac
He Nathan, I would create an data type (SpaceObject), which holds the Position and an object. Then I create a typeclass for SpaceObject, which has the function move in it. Functions which all objects have are moved in the typeclass: type Position = (Double, Double) data SpaceObject a = SO a Position data RocketObject = RocketObject { stuff :: String } data SpaceShipObject = SpaceShipObject { bla :: Int } type Rocket = SpaceObject RocketObject type SpaceShip = SpaceObject SpaceShipObject class ScreenObject a where move :: a -> Position -> a instance ScreenObject (SpaceObject obj) where move (SO obj (x,y) ) (dx, dy) = SO obj (x + dx, y + dy) ~ ~ ~ ~ On Tue, May 18, 2010 at 5:21 AM, <haskell@lonely-star.org> wrote:
Hi,
I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode. In C++, I would do (simplified):
class ScreenObject { float x,y; void move(dx,dy){x+=dx;y+=dy;} };
class Spaceship : public ScreenObject { void shoot(){...} };
class Rocket : public ScreenObject { void explode(){...} };
But what would I do in haskell? Ok, I can define a typeclass "ScreenObjectType" that has a move function (taking an object, retuning an moved object). But I do not want to implement "move" for both Spaceship and Rocket. Can I somehow give a default implementation for move that works on any datatype having an "x" and "y" element? Or what would I do? Can I somehow define a "base datatype" holding a x and y member form which Spaceship and Rocket derive? I feel like I am thinking to much OOP here. But the point is, I guess, that I want to avoid code duplication!
So I guess, it comes down to the questions: How would you model the scenario described above in haskell?
Thanks! Nathan _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- Flatliner ICT Service, Email: Edgar.klerks@gmail.com, Tel: +31727851429 Fax: +31848363080 Skype: edgar.klerks Website: flatlinerict.nl Adres: Koelmalaan 258, 1813JD, Alkmaar Nederland
Hi, Thanks, I think I am starting to get it :). But let me extend my example. Assume, (in C++) ScreenObject also has a abstract function "update" implemented in SpaceShip and Rocket and doing something completly different for both of them. Now there are a lot of ScreenObjects in the "world" which have to be updated in every frame. This is done by having a list of pointers to ScreenObjects (objects) and a updateWorld function which looks like this (simplified): void updateWorld() { for(o in objects) o->update(); } How would you model this in haskell? Thanks! Nathan On Tue, 18 May 2010 11:33:08 +0200 edgar klerks <edgar.klerks@gmail.com> wrote:
He Nathan,
I would create an data type (SpaceObject), which holds the Position and an object. Then I create a typeclass for SpaceObject, which has the function move in it. Functions which all objects have are moved in the typeclass:
type Position = (Double, Double)
data SpaceObject a = SO a Position
data RocketObject = RocketObject { stuff :: String }
data SpaceShipObject = SpaceShipObject { bla :: Int }
type Rocket = SpaceObject RocketObject type SpaceShip = SpaceObject SpaceShipObject
class ScreenObject a where move :: a -> Position -> a
instance ScreenObject (SpaceObject obj) where move (SO obj (x,y) ) (dx, dy) = SO obj (x + dx, y + dy) ~
~
~
~
On Tue, May 18, 2010 at 5:21 AM, <haskell@lonely-star.org> wrote:
Hi,
I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode. In C++, I would do (simplified):
class ScreenObject { float x,y; void move(dx,dy){x+=dx;y+=dy;} };
class Spaceship : public ScreenObject { void shoot(){...} };
class Rocket : public ScreenObject { void explode(){...} };
But what would I do in haskell? Ok, I can define a typeclass "ScreenObjectType" that has a move function (taking an object, retuning an moved object). But I do not want to implement "move" for both Spaceship and Rocket. Can I somehow give a default implementation for move that works on any datatype having an "x" and "y" element? Or what would I do? Can I somehow define a "base datatype" holding a x and y member form which Spaceship and Rocket derive? I feel like I am thinking to much OOP here. But the point is, I guess, that I want to avoid code duplication!
So I guess, it comes down to the questions: How would you model the scenario described above in haskell?
Thanks! Nathan _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
You would likely not use a void function and instead map over the objects in the world: updateWorld :: World -> World updateWorld = fmap update This way your functions can remain pure. On Tue, May 18, 2010 at 9:28 PM, <haskell@lonely-star.org> wrote:
Hi,
Thanks, I think I am starting to get it :). But let me extend my example. Assume, (in C++) ScreenObject also has a abstract function "update" implemented in SpaceShip and Rocket and doing something completly different for both of them. Now there are a lot of ScreenObjects in the "world" which have to be updated in every frame. This is done by having a list of pointers to ScreenObjects (objects) and a updateWorld function which looks like this (simplified):
void updateWorld() { for(o in objects) o->update(); }
How would you model this in haskell? Thanks! Nathan
On Tue, 18 May 2010 11:33:08 +0200 edgar klerks <edgar.klerks@gmail.com> wrote:
He Nathan,
I would create an data type (SpaceObject), which holds the Position and an object. Then I create a typeclass for SpaceObject, which has the function move in it. Functions which all objects have are moved in the typeclass:
type Position = (Double, Double)
data SpaceObject a = SO a Position
data RocketObject = RocketObject { stuff :: String }
data SpaceShipObject = SpaceShipObject { bla :: Int }
type Rocket = SpaceObject RocketObject type SpaceShip = SpaceObject SpaceShipObject
class ScreenObject a where move :: a -> Position -> a
instance ScreenObject (SpaceObject obj) where move (SO obj (x,y) ) (dx, dy) = SO obj (x + dx, y + dy) ~
~
~
~
On Tue, May 18, 2010 at 5:21 AM, <haskell@lonely-star.org> wrote:
Hi,
I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode. In C++, I would do (simplified):
class ScreenObject { float x,y; void move(dx,dy){x+=dx;y+=dy;} };
class Spaceship : public ScreenObject { void shoot(){...} };
class Rocket : public ScreenObject { void explode(){...} };
But what would I do in haskell? Ok, I can define a typeclass "ScreenObjectType" that has a move function (taking an object, retuning an moved object). But I do not want to implement "move" for both Spaceship and Rocket. Can I somehow give a default implementation for move that works on any datatype having an "x" and "y" element? Or what would I do? Can I somehow define a "base datatype" holding a x and y member form which Spaceship and Rocket derive? I feel like I am thinking to much OOP here. But the point is, I guess, that I want to avoid code duplication!
So I guess, it comes down to the questions: How would you model the scenario described above in haskell?
Thanks! Nathan _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
Hey, Yes, that makes sense. Still, how would the "World" object look? How do I do a list of abstract base classes in haskell? On Tue, 18 May 2010 22:08:31 +0800 Lyndon Maydwell <maydwell@gmail.com> wrote:
You would likely not use a void function and instead map over the objects in the world:
updateWorld :: World -> World updateWorld = fmap update
This way your functions can remain pure.
On Tue, May 18, 2010 at 9:28 PM, <haskell@lonely-star.org> wrote:
Hi,
Thanks, I think I am starting to get it :). But let me extend my example. Assume, (in C++) ScreenObject also has a abstract function "update" implemented in SpaceShip and Rocket and doing something completly different for both of them. Now there are a lot of ScreenObjects in the "world" which have to be updated in every frame. This is done by having a list of pointers to ScreenObjects (objects) and a updateWorld function which looks like this (simplified):
void updateWorld() { for(o in objects) o->update(); }
How would you model this in haskell? Thanks! Nathan
On Tue, 18 May 2010 11:33:08 +0200 edgar klerks <edgar.klerks@gmail.com> wrote:
He Nathan,
I would create an data type (SpaceObject), which holds the Position and an object. Then I create a typeclass for SpaceObject, which has the function move in it. Functions which all objects have are moved in the typeclass:
type Position = (Double, Double)
data SpaceObject a = SO a Position
data RocketObject = RocketObject { stuff :: String }
data SpaceShipObject = SpaceShipObject { bla :: Int }
type Rocket = SpaceObject RocketObject type SpaceShip = SpaceObject SpaceShipObject
class ScreenObject a where move :: a -> Position -> a
instance ScreenObject (SpaceObject obj) where move (SO obj (x,y) ) (dx, dy) = SO obj (x + dx, y + dy) ~
~
~
~
On Tue, May 18, 2010 at 5:21 AM, <haskell@lonely-star.org> wrote:
Hi,
I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode. In C++, I would do (simplified):
class ScreenObject { float x,y; void move(dx,dy){x+=dx;y+=dy;} };
class Spaceship : public ScreenObject { void shoot(){...} };
class Rocket : public ScreenObject { void explode(){...} };
But what would I do in haskell? Ok, I can define a typeclass "ScreenObjectType" that has a move function (taking an object, retuning an moved object). But I do not want to implement "move" for both Spaceship and Rocket. Can I somehow give a default implementation for move that works on any datatype having an "x" and "y" element? Or what would I do? Can I somehow define a "base datatype" holding a x and y member form which Spaceship and Rocket derive? I feel like I am thinking to much OOP here. But the point is, I guess, that I want to avoid code duplication!
So I guess, it comes down to the questions: How would you model the scenario described above in haskell?
Thanks! Nathan _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
World could be anything really, maybe a list of objects, or something much more involved. From my use of fmap I've implied that it is an instance of the Functor typeclass, but that was only a suggestion. I'm not sure what you're after with respect the the abstract base classes, but there's this diagram floating around of the haskell98 typeclasses: [ http://www.uni-bonn.de/~manfear/haskell-classhierarchy.php ]. Maybe this will help? I usually use the ":info" command on a class in ghci to find out some more about it, but I still have trouble finding a good class to use for any particular problem. Hope this was helpful. On Tue, May 18, 2010 at 10:29 PM, Nathan Huesken <haskell@lonely-star.org> wrote:
Hey,
Yes, that makes sense. Still, how would the "World" object look? How do I do a list of abstract base classes in haskell?
On Tue, 18 May 2010 22:08:31 +0800 Lyndon Maydwell <maydwell@gmail.com> wrote:
You would likely not use a void function and instead map over the objects in the world:
updateWorld :: World -> World updateWorld = fmap update
This way your functions can remain pure.
On Tue, May 18, 2010 at 9:28 PM, <haskell@lonely-star.org> wrote:
Hi,
Thanks, I think I am starting to get it :). But let me extend my example. Assume, (in C++) ScreenObject also has a abstract function "update" implemented in SpaceShip and Rocket and doing something completly different for both of them. Now there are a lot of ScreenObjects in the "world" which have to be updated in every frame. This is done by having a list of pointers to ScreenObjects (objects) and a updateWorld function which looks like this (simplified):
void updateWorld() { for(o in objects) o->update(); }
How would you model this in haskell? Thanks! Nathan
On Tue, 18 May 2010 11:33:08 +0200 edgar klerks <edgar.klerks@gmail.com> wrote:
He Nathan,
I would create an data type (SpaceObject), which holds the Position and an object. Then I create a typeclass for SpaceObject, which has the function move in it. Functions which all objects have are moved in the typeclass:
type Position = (Double, Double)
data SpaceObject a = SO a Position
data RocketObject = RocketObject { stuff :: String }
data SpaceShipObject = SpaceShipObject { bla :: Int }
type Rocket = SpaceObject RocketObject type SpaceShip = SpaceObject SpaceShipObject
class ScreenObject a where move :: a -> Position -> a
instance ScreenObject (SpaceObject obj) where move (SO obj (x,y) ) (dx, dy) = SO obj (x + dx, y + dy) ~
~
~
~
On Tue, May 18, 2010 at 5:21 AM, <haskell@lonely-star.org> wrote:
Hi,
I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode. In C++, I would do (simplified):
class ScreenObject { float x,y; void move(dx,dy){x+=dx;y+=dy;} };
class Spaceship : public ScreenObject { void shoot(){...} };
class Rocket : public ScreenObject { void explode(){...} };
But what would I do in haskell? Ok, I can define a typeclass "ScreenObjectType" that has a move function (taking an object, retuning an moved object). But I do not want to implement "move" for both Spaceship and Rocket. Can I somehow give a default implementation for move that works on any datatype having an "x" and "y" element? Or what would I do? Can I somehow define a "base datatype" holding a x and y member form which Spaceship and Rocket derive? I feel like I am thinking to much OOP here. But the point is, I guess, that I want to avoid code duplication!
So I guess, it comes down to the questions: How would you model the scenario described above in haskell?
Thanks! Nathan _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
On 18 May 2010 15:29, Nathan Huesken <haskell@lonely-star.org> wrote: [SNIP]
Yes, that makes sense. Still, how would the "World" object look?
Hi Nathan I don't know how appropriate it would be for a game - but Malcolm Wallace and colleagues presented a scene graph in this paper: Huge Data but Small Programs: Visualization Design via Multiple Embedded DSLs http://eprints.whiterose.ac.uk/5000/1/padl09.pdf ... see 5.2 Rendering and Interaction It might make a concrete starting point. There is a different scene graph on Hackage, but it has a somewhat more complicated implementation. Best wishes Stephen
Hey, I think I am getting grasp of it. Thanks for all the help!
On Tue, 18 May 2010 05:21:38 +0200, <haskell@lonely-star.org> wrote:
Hi,
I learning haskell and I am trying to understand how model certain things in it. As I have been doing a lot of C++ programming so far. Let's imagine we want to write a game. In the game there are spaceships and rocks (image something like astroids :) ). Now both spaceships and rocks have a position and can move. Spaceships can shoot, while rocks can explode.
There is a well documented implementation, called wxAsteroids; see http://www.haskell.org/haskellwiki/WxAsteroids Regards, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html --
participants (7)
-
edgar klerks -
haskell@lonely-star.org -
Henk-Jan van Tuyl -
Isaac Dupree -
Lyndon Maydwell -
Nathan Huesken -
Stephen Tetley