[C][enums][newbie] What is natural Haskell representation of such enum?

What is natural Haskell representation of such enum? enum TypeMask { UNIT, GAMEOBJECT, CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT }; More sophisticated question is: and what data structures must be used when converting this naturally one to Haskell? // 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ... CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };

Performing bit-mask operations is possible via the Data.Bits operations (on
elements of type Word8 or Word16, etc.). But I must say, it doesn't seem
very `natural` in Haskell, nor even in other languages. It crosses lines,
binding abstraction to representation in order to improve efficiency.
The natural way in Haskell to model model `CREATURE_OR_GAMEOBJECT` would
simply be as a function (e.g. of type Object -> Bool, or ObjectType ->
Bool).
Regards,
Dave
2012/1/22 Данило Глинський
What is natural Haskell representation of such enum?
enum TypeMask { UNIT, GAMEOBJECT,
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT };
More sophisticated question is: and what data structures must be used when converting this naturally one to Haskell?
// 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ...
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Данило Глинський wrote:
What is natural Haskell representation of such enum?
enum TypeMask { UNIT, GAMEOBJECT,
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT };
data ObjectType = Unit | GameObject creatureOrGameObject :: ObjectType -> Bool creatureOrGameObject Unit = True creatureOrGameObject GameObject = True creatureOrGameObject _ = False
More sophisticated question is: and what data structures must be used when converting this naturally one to Haskell?
// 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ...
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };
Pretty much as above, add all the different single bit masks as constructors to ObjectType and define functions for the ones that are a combination of one ore more constructor. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

I may be curious to see how you intend to use such enum...
It is very C-wise, I'm not sure it will be very handy, but I need some
context.
2012/1/22 Данило Глинський
What is natural Haskell representation of such enum?
enum TypeMask { UNIT, GAMEOBJECT,
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT };
More sophisticated question is: and what data structures must be used when converting this naturally one to Haskell?
// 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ...
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

2012/1/22 Данило Глинський
What is natural Haskell representation of such enum? enum TypeMask { UNIT, GAMEOBJECT,
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT };
I don't think that definition makes any sense in C, because UNIT is 0, so UNIT | GAMEOBJECT == GAMEOBJECT == 1 Nevertheless, in Haskell something vaguely similar might be: data TypeMask = UNIT | GAMEOBJECT | CREATURE_OR_GAMEOBJECT
// 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ...
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };
import Data.Bits data TypeMask = UNIT | GAMEOBJECT | CREATURE_OR_GAMEOBJECT | WORLDOBJECT instance Enum TypeMask where fromEnum UNIT = 0x4 fromEnum GAMEOBJECT = 0x8 fromEnum CREATURE_OR_GAMEOBJECT = fromEnum UNIT .|. fromEnum GAMEOBJECT fromEnum WORLDOBJECT = fromEnum UNIT .|. fromEnum PLAYER .|. fromEnum GAMEOBJECT .|. fromEnum DYNAMICOBJECT .|. fromEnum CORPSE toEnum 0x4 = UNIT toEnum 0x8 = GAMEOBJECT toEnum _ = error "unspecified enumeration value of type TypeMask" isCreatureOrGameObject :: Int -> Bool isCreatureOrGameObject x = (x .|. fromEnum CREATURE_OR_GAMEOBJECT) /= 0 isWorldObject :: Int -> Bool isWorldObject x = (x .|. fromEnum WORLDOBJECT) /= 0 -- But fundamentally, this is not an idiomatic Haskell way of doing things. -- The other posts in this thread have shown more Haskell-ish translations.

Thanks. This and previous email are answers to question I asked. But not
the answer to question I mean.
I'll describe the whole task, as Yves Parès suggested.
I'm trying to convert C++ code to Haskell. I have such hierarchy: class
Object, class Item : Object, class Container : Item. Another one example:
class Unit : Object, class Player : Unit. Each constructor do things like
this:
Object::Object()
{
objectType = TYPEMASK_OBJECT;
// ... lots of code ...
}
Item::Item()
{
objectType |= TYPEMASK_ITEM;
// ...
}
Container::Container(): Item()
{
objectType |= (TYPEMASK_ITEM | TYPEMASK_CONTAINER);
// ...
}
What is objectType? This field is used when a networksend packet is
created. In the packet it is 1 byte of flags, so it is in object hierarchy.
So the question was: what type should objectType field have in Haskell? I
think it must not mimic enum. What the structure have I to use? There is
one more problem - there may be lots of objects, lots of, so memory
efficiency is also suggested.
And side question: what to do with classes? =) Maybe there is simple rule
to convert OO hierarchy to FP.
23 січня 2012 р. 12:15 Malcolm Wallace
2012/1/22 Данило Глинський
What is natural Haskell representation of such enum? enum TypeMask { UNIT, GAMEOBJECT,
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT };
I don't think that definition makes any sense in C, because UNIT is 0, so UNIT | GAMEOBJECT == GAMEOBJECT == 1
Nevertheless, in Haskell something vaguely similar might be:
data TypeMask = UNIT | GAMEOBJECT | CREATURE_OR_GAMEOBJECT
// 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ...
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };
import Data.Bits data TypeMask = UNIT | GAMEOBJECT | CREATURE_OR_GAMEOBJECT | WORLDOBJECT instance Enum TypeMask where fromEnum UNIT = 0x4 fromEnum GAMEOBJECT = 0x8 fromEnum CREATURE_OR_GAMEOBJECT = fromEnum UNIT .|. fromEnum GAMEOBJECT fromEnum WORLDOBJECT = fromEnum UNIT .|. fromEnum PLAYER .|. fromEnum GAMEOBJECT .|. fromEnum DYNAMICOBJECT .|. fromEnum CORPSE
toEnum 0x4 = UNIT toEnum 0x8 = GAMEOBJECT toEnum _ = error "unspecified enumeration value of type TypeMask"
isCreatureOrGameObject :: Int -> Bool isCreatureOrGameObject x = (x .|. fromEnum CREATURE_OR_GAMEOBJECT) /= 0
isWorldObject :: Int -> Bool isWorldObject x = (x .|. fromEnum WORLDOBJECT) /= 0
-- But fundamentally, this is not an idiomatic Haskell way of doing things. -- The other posts in this thread have shown more Haskell-ish translations.

If you want a simple translation, use Word8 (from Data.Word) for the type
and use Data.Bits for operations on it just like in C++. This would offer
you storage efficiency (if stored as a strict field).
If you want idiomatic Haskell, constructor of the form:
data ObjectType = Object | Item | Container | Unit | Player, etc.
Then simply put intelligence into the `isContainer` or `toWord8`, etc.
translations. This latter approach will be more extensible in the long run,
since you might find you want some parameterized object types.
Re: OO Classes and Haskell
If your classes are more like `interfaces`, you could use Typeclasses to
model them. Otherwise, look into OOHaskell. But I think your program
architecture will simply be different in idiomatic Haskell than in
idiomatic C++.
Regards,
Dave
On Mon, Jan 23, 2012 at 1:14 PM, Daniel Hlynskyi
Thanks. This and previous email are answers to question I asked. But not the answer to question I mean. I'll describe the whole task, as Yves Parès suggested.
I'm trying to convert C++ code to Haskell. I have such hierarchy: class Object, class Item : Object, class Container : Item. Another one example: class Unit : Object, class Player : Unit. Each constructor do things like this:
Object::Object() { objectType = TYPEMASK_OBJECT; // ... lots of code ... }
Item::Item() { objectType |= TYPEMASK_ITEM; // ... }
Container::Container(): Item() { objectType |= (TYPEMASK_ITEM | TYPEMASK_CONTAINER); // ... }
What is objectType? This field is used when a networksend packet is created. In the packet it is 1 byte of flags, so it is in object hierarchy.
So the question was: what type should objectType field have in Haskell? I think it must not mimic enum. What the structure have I to use? There is one more problem - there may be lots of objects, lots of, so memory efficiency is also suggested. And side question: what to do with classes? =) Maybe there is simple rule to convert OO hierarchy to FP.
23 січня 2012 р. 12:15 Malcolm Wallace
написав: 2012/1/22 Данило Глинський
What is natural Haskell representation of such enum? enum TypeMask { UNIT, GAMEOBJECT,
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT };
I don't think that definition makes any sense in C, because UNIT is 0, so UNIT | GAMEOBJECT == GAMEOBJECT == 1
Nevertheless, in Haskell something vaguely similar might be:
data TypeMask = UNIT | GAMEOBJECT | CREATURE_OR_GAMEOBJECT
// 1-byte flaged enum enum TypeMask { // ... UNIT = 0x0004, GAMEOBJECT = 0x0008, // ...
CREATURE_OR_GAMEOBJECT = UNIT | GAMEOBJECT WORLDOBJECT = UNIT | PLAYER | GAMEOBJECT | DYNAMICOBJECT | CORPSE // ... even more enum combos ... };
import Data.Bits data TypeMask = UNIT | GAMEOBJECT | CREATURE_OR_GAMEOBJECT | WORLDOBJECT instance Enum TypeMask where fromEnum UNIT = 0x4 fromEnum GAMEOBJECT = 0x8 fromEnum CREATURE_OR_GAMEOBJECT = fromEnum UNIT .|. fromEnum GAMEOBJECT fromEnum WORLDOBJECT = fromEnum UNIT .|. fromEnum PLAYER .|. fromEnum GAMEOBJECT .|. fromEnum DYNAMICOBJECT .|. fromEnum CORPSE
toEnum 0x4 = UNIT toEnum 0x8 = GAMEOBJECT toEnum _ = error "unspecified enumeration value of type TypeMask"
isCreatureOrGameObject :: Int -> Bool isCreatureOrGameObject x = (x .|. fromEnum CREATURE_OR_GAMEOBJECT) /= 0
isWorldObject :: Int -> Bool isWorldObject x = (x .|. fromEnum WORLDOBJECT) /= 0
-- But fundamentally, this is not an idiomatic Haskell way of doing things. -- The other posts in this thread have shown more Haskell-ish translations.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 2012-01-23 13.45.50 -0800, David Barbour wrote:
If your classes are more like `interfaces`, you could use Typeclasses to model them. Otherwise, look into OOHaskell. But I think your program architecture will simply be different in idiomatic Haskell than in idiomatic C++.
If your OO is very design patterned, and especially if it prefers composition over inheritence, you can port it sorta directly, sometimes. For example, all the classes that implement an interface become a sum type, and their methods are functions that take a value of the sum type. interface MusicCompilation { def trackListing() : [Song] } class Record implements MusicCompilation { ... } class BlogPost implements MusicCompilation { ... } Could translate to data MusicCompilation = Record [Song] | BlogPost [Song] trackListing (Record xs) = xs trackListing (BlogPost xs) = xs The more your OO looks like C, the harder this will be.
participants (7)
-
Daniel Hlynskyi
-
David Barbour
-
Erik de Castro Lopo
-
Malcolm Wallace
-
Mike Burns
-
Yves Parès
-
Данило Глинський