Haskell:数据类型的多重声明

时间:2017-08-21 07:59:41

标签: haskell

创建数据类型时遇到了一些问题。

我有两种数据类型,足球和网球

data Football a  = Football
  { players       :: Players a    
  , Stadium       :: Stadium  a
  }     

data Tennis a  = Tennis
  { players1      :: Players a    
  , Stadium1      :: Stadium  a
  }

我想创建另一个数据类型Sport使用数据类型football和tennis作为构造函数 data Sport a = Football a | Tennis a 我得到以下错误,足球的多个声明我不明白我做错了什么。

祝你好运

1 个答案:

答案 0 :(得分:8)

你的想法在精神上是正确的,但Haskell使用标记的联合(也称为“歧视联盟”,“不相交的联盟”,“变体”和“和类型”)。这意味着你需要一个额外的标签来确定Sport是用Football构建的,还是用Tennis构建的。

data Sport = SportFootball Football | SportTennis Tennis

这些标记在Haskell中称为数据构造函数。也就是说,这定义了构造函数SportFootball :: Football -> Sport和构造函数SportTennis :: Tennis -> Sport

假设Haskell不需要这个额外的标签,那么这种类型会是什么?

data UntaggedInt = Int | Int

未标记的联合应具有属性(x | x) = x,因此必须等同于:

data UntaggedInt = Int

鉴于标记的联合,我们可以定义:

data TaggedInt = This Int | That Int

也就是说,标记的联合不是幂等

还要考虑没有构造函数的其他事情。假设我们有一个定义,如:

data UntaggedLists = String | [String]

现在我们的任务是找到表达式"hello world"的类型。类型应为String还是UntaggedLists?然后假设我们有另一个类似的定义:

data AnotherUntaggedLists = String | [String]

UntaggedListsAnotherUntaggedLists是相同的类型吗?

这些不是无法回答的问题,但它确实表明在有标签之间存在深刻的系统差异。