[Haskell-beginners] How to model this in haskell, get rid of my
OO thinking?
Lyndon Maydwell
maydwell at gmail.com
Tue May 18 10:45:02 EDT 2010
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 at 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 at 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 at 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 at 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 at 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 at haskell.org
>> >> > http://www.haskell.org/mailman/listinfo/beginners
>> >> >
>> >>
>> >>
>> >>
>> >
>> > _______________________________________________
>> > Beginners mailing list
>> > Beginners at haskell.org
>> > http://www.haskell.org/mailman/listinfo/beginners
>> >
>>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
More information about the Beginners
mailing list