2014-04-27 59 views
9

在Haskell中,是否可以在函数范围内定义数据类型?Haskell:定义一个函数范围的新数据类型

例如,我正在写一个函数f :: [(Char, Int)] -> [(Char, String)]。在函数的实现中,我将从输入列表构建一棵树,然后遍历树来构建输出列表。一种解决方案是定义一个特定于我的问题的新的Tree数据类型,以及两个辅助函数,一个用于将输入列表转换为树,另一个用于遍历Tree并构建输出列表。

现在,通过将这两个辅助函数放入where子句中,可以很容易地将它们拉入f的范围,但是临时nonce类型树呢?通过在函数范围之外定义它来污染名称空间似乎很难,但我不知道要如何去做。

对于上下文,事实证明我正在计算霍夫曼编码。在这一点上,我并不特别感兴趣的是找到一种替代算法,因为我怀疑它在Haskell中通常会在助手函数之间定义助手数据类型方面很有用,所以我对这种方法的一般方法感兴趣。

+12

所有数据类型声明都必须位于顶层。如果您不想污染名称空间,则不要导出数据类型。 – user2407038

+0

[This](http://stackoverflow.com/questions/15320391/proposal-for-local-data-declarations-instances)可能是相关的。 – is7s

回答

6

不,这是不可能的。

在Haskell模块和合格的导入应该解决所有的名称空间问题,如你的或臭名昭着的记录字段名称冲突。

所以你想让一个类型只对某个函数可见?将该类型和该函数放在一个新模块中,并(可选)仅导出该函数。

当然,通过遵循这个约定,你将会得到比平常更多的模块,但是如果你仔细想想,这与其他许多语言实际上并没有什么不同。例如,在Java中,将每个类放在一个单独的文件中是常规的,不管这个类有多小。

我不得不提到,尽管离社区大多数人实际上都遵循这个约定。你经常可以看到用来解决这个问题的神秘名字。就我个人而言,我不觉得这样的方法很干净,宁愿推荐使用模块。