【问题标题】:haskell sum type multiple declaration errorhaskell sum 类型多重声明错误
【发布时间】:2015-12-09 02:30:46
【问题描述】:
data A=A
data B=B
data AB=A|B

这使得 A 和 B 的总和类型为 AB。

但最后一行导致编译错误“B 的多个声明”

我也试过这样的:

data A=Int|Bool

它编译。但是为什么 ghc 不允许我为用户定义的类型创建 sum 类型?

【问题讨论】:

  • 哇!这次编辑完全改变了问题的细节,使所有的答案看起来有点愚蠢。这不是真正推荐的方式。相反,如果您发现第一个问题后仍然感到困惑,请打开一个新问题,详细说明您的新问题、它与前一个问题的不同之处以及您仍然感到困惑的原因。
  • 对不起,上一个实际上是一个简化的...经过一些实验,我发现最好发布原始的,对不起..感谢您的详细打字!你想更新你的答案吗?
  • @doofin: 不......你应该恢复你的编辑并打开一个新问题

标签: haskell types algebraic-data-types


【解决方案1】:

必须标记总和类型。 a+a 必须有两个来自a注入

要了解代数数据类型的工作原理,举一个简单的例子:

data X = A | B C

这定义了一个新的类型构造函数X,以及数据构造函数ABB 构造函数接受/持有一个 C 类型的参数。

Haskell 中主要的规范求和类型是Either

data Either a b = Left a | Right b

【讨论】:

    【解决方案2】:

    你被愚弄了。你认为当你写data A=Int|Bool时你是说A类型的值可以是Int类型的值或Bool类型的值;但是您实际上说的是有两个新的值级构造函数,分别名为IntBool,每个都不包含任何信息,类型为A。同样,您认为data AB=A|B 表示您可以是A 类型或B 类型,但实际上您是说您可以拥有value Avalue B.

    要记住的关键是有两个命名空间,类型级别和术语级别,并且它们是不同的。

    这是一个如何正确操作的简单示例:

    data A=A
    data B=B
    data AB=L A|R B
    

    最后一行声明了两个新的术语级构造函数,LRL 构造函数的值是 type A,而 R 构造函数的值是 type B

    您可能还喜欢Either 类型,定义如下:

    data Either a b = Left a | Right b
    

    如果您愿意,可以使用它来实现您的 AB

    type AB = Either A B
    

    同样,您可以将Either Int Bool 用于IntBool 的标记联合。

    【讨论】:

    • 鉴于AB 都没有携带额外的信息,人们可能会完全丢弃它们并使用data AB = A | B,但如果没有额外的代码,这很难看到。
    • @Zeta 我假设data A=Adata B=B 只是更有趣的数据类型的占位符。
    【解决方案3】:

    因为使用数据构造函数AB 创建的值的类型会不明确。例如,当我有a = B 时,a 的类型是什么?是A还是AB

    您应该考虑使用不同的数据构造函数,如下所示:

    data A = MkA
    data B = MkB
    data AB = A A | B B
    

    【讨论】:

    • 我猜你的意思是data AB = A A | B B。毕竟应该是A和B的sum类型。
    • 啊,对了,谢谢指正,本来就是这么写的
    【解决方案4】:

    当您说data AB = A | B 时,您指的不是类型 AB,而是定义数据构造函数 A 和@ 987654325@。这些与前面几行定义的构造函数有冲突。

    如果你想创建一个类型 ABAB 的总和,你必须提供包装类型 AB 的数据构造函数,例如:

    data AB = ABA A | ABB B
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多