如何使用Haskell类型构造函数作为枚举?

时间:2014-01-20 06:54:10

标签: haskell types type-constructor

我正在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 | ...

但有没有办法避免重复数据构造函数和类型构造函数?

1 个答案:

答案 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 {}格式是在将来可能获取更多参数的构造函数匹配的最佳方式,因为它可以避免在发生这种情况时更新匹配代码。)