我正在Haskell中编写一个使用查找表的程序。
例如
type Table = [(Object, FilePath)]
data Object = Player { pName :: String }
我想以Player
可以成为查找键的方式构建它:
[(Player, "data/players"), ...]
如果我添加了另一个Object
类型Monster
,我的表格可能如下:
[(Player, "data/players"), (Monster, "data/mons"), ...]
但是,我Table
的类型定义表明我正在查找实例化对象,实际上,我只是想检查它是否是一个类型构造函数或其他。
我该怎么做?
编辑:
我想我想要这样的东西:
data ObjectType = Player | Monster | ...
但有没有办法避免重复数据构造函数和类型构造函数?
答案 0 :(得分:6)
你不能以你描述的方式真正做到这一点。由于Player
采用了参数(pName
),因此Player
本身的类型为String -> Object
,因此它不适合您的Table
类型。< / p>
正如您的编辑中所建议的那样,您应该创建一个单独的枚举类型,而不需要专门针对Table
的参数:
data ObjectType = PlayerType | MonsterType | ...
根据Object
的其他构造函数的定义方式,您可以避免重复,例如。
data Object = Object { objectType :: ObjectType, name :: String }
但这确实假设每种Object
只有一个name
参数而没有别的。
编辑:
在反思时,我想知道查找表结构是否有意义。你可以用这个替换表:
lookupPath :: Object -> String
lookupPath (Player {}) = "data/players"
lookupPath (Monster {}) = "data/mons"
...
这种格式会使诸如将表保存到磁盘之类的操作变得更加困难,但确实会捕获您想要在没有参数的情况下匹配对象的意图。
(匹配的Player {}
格式是在将来可能获取更多参数的构造函数匹配的最佳方式,因为它可以避免在发生这种情况时更新匹配代码。)