I am writing a program in Haskell that makes use of a lookup table.
eg.
type Table = [(Object, FilePath)]
data Object = Player { pName :: String }
I want to construct this in such a way that Player
can be a lookup key:
[(Player, "data/players"), ...]
If I added another Object
type Monster
, my table might look like:
[(Player, "data/players"), (Monster, "data/mons"), ...]
However, my type definition of a Table
suggests that I am looking up instantiated objects when, really, I just want to check if it's one type constructor or the other.
How do I go about doing this?
EDIT:
I suppose I want something like:
data ObjectType = Player | Monster | ...
but is there a way to avoid duplication of the data constructor and type constructor?
You can't really do this in the way you describe. Because
Player
takes an argument (pName
), the type ofPlayer
itself isString -> Object
, so it won't fit in yourTable
type properly.As suggested in your edit, you should probably make a separate enumeration type without arguments specifically for
Table
:Depending on how the other constructors of
Object
will be defined, you might be able to avoid duplication, e.g.but that does assume that every kind of
Object
will have exactly onename
argument and nothing else.EDIT:
On reflection, I wonder if having a lookup table structure makes sense in the first place. You could replace the table with this:
This format will make it harder to do things like persisting the table to disk, but does exactly capture your intention of wanting to match on the object without its parameters.
(The
Player {}
format for the match is the best way to match on constructors that may acquire more arguments in future, as it saves you from having to update the matching code when this happens.)