Haskell设置数据类型/数据结构

时间:2011-09-14 19:17:05

标签: haskell data-structures set compare equals

我想要做的是在Haskell中创建一个类型Set来表示一个通用(多态)集ex。 {1,'x',"aasdf",Phi}

首先我要清楚在我的程序中我想将Phi(空集)视为属于所有集合的东西

这是我的代码

data Set a b= Phi | Cons a (Set a b)
deriving (Show,Eq,Ord)


isMember Phi _ = True
isMember _ Phi = False
isMember x (Cons a b) = if x==a
               then True
               else isMember x b
我面临着一些问题:

  1. 我希望isMember类型为

    isMember :: Eq a => a -> Set a b -> Bool
    

    但根据我的代码,它是

    isMember :: Eq a => Set a b -> Set (Set a b) c -> Bool
    
  2. 如果我有一组不同的时间==运算符无法正常工作,那么我需要一些帮助:D

3 个答案:

答案 0 :(得分:6)

关于你的类型错误,问题看起来像我的第一个句子:

isMember Phi _ = True

这是一个要编写的奇数子句,因为Phi是整个集合,而不是集合元素。只是删除它应该给你一个你期望的类型的功能。

观察到你的Set类型从不使用它的第二个类型参数,所以它可以改为编写为

data Set a = Phi | Cons a (Set a)

......那时你应该只使用[a],因为它是同构的,并且已经为使用和滥用它们而编写了大量函数。

最后,你要求能够把不同类型的东西放进去。简短的回答是Haskell并没有真正摆脱那种方式。这一切都是为了确切地知道什么类型的东西在编译时,这与你的建议并不完全兼容。实际上有一些方法可以做到这一点;但是,我强烈建议在尝试取消债券之前,先熟悉Haskell特有的类型束缚品牌。

答案 1 :(得分:5)

A)这样做几乎总是不是你真正想要的。

B)通过嵌入动态类型(Dynamic)到使用非常复杂的类型(HList),有多种方法可以做到这一点。

C)这是一个描述一些方法和问题的页面:http://www.haskell.org/haskellwiki/Heterogenous_collections

D)如果您真的要这样做,我建议HListhttp://homepages.cwi.nl/~ralf/HList/

E)但是如果你开始查看文档/ HList文件并发现自己无可救药地混淆了,那就回到动态解决方案(或者更好的是,重新考虑你为什么需要这个),并在你显着的时候回到HLists更适合Haskell。

(哦,是的,该页面上描述的存在主义解决方案可能是一个糟糕的主意,因为它几乎从未对你做过任何特别有用的事情。)

答案 2 :(得分:2)

您尝试做的事情非常困难,因为默认情况下Haskell不存储任何类型信息。对这些事情非常有用的两个模块是Data.TypeableData.Dynamic。它们支持存储单态(!)类型并支持动态单态输入。

我之前没有尝试过这样的代码,但我有一些想法可以实现:

  1. 您的集合中的每个元素都是以下内容的三倍(四倍):

    • 存储数据类型的TypeRep
    • 价值本身,被强制转换为Any
    • 比较函数(你只能使用单态值,你不得不存储上下文)
    • 相似,是show值的函数。
  2. 您的集合实际上有两个维度,首先是TypeRep的树,而不是值列表。

  3. 每当您插入一个值时,您将其强制转换为Any并将所有必需的内容与它一起存储,如(1)中所述,并将其置于(2)中的正确位置

  4. 如果要查找元素,可以生成它TypeRep并找到正确类型的子树。然后,您只需将每个子元素与您要查找的值进行比较。

  5. 这只是一些随意的想法。我想使用Dynamic实际上要容易得多。