【问题标题】:Haskell Tuple Size LimitHaskell 元组大小限制
【发布时间】:2011-02-28 00:49:52
【问题描述】:

为什么我不能在 Haskell 中构造大元组?为什么有元组大小限制?

Prelude> (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)

<interactive>:1:0:
    No instance for (Show
                       (t,
                        t1,
                        t2,
                        ...
                        t23))
      arising from a use of `print' at <interactive>:1:0-48
    Possible fix:
      add an instance declaration for
      (Show
         (t,
          t1,
          t2,
          ...
          t23))
    In a stmt of a 'do' expression: print it

【问题讨论】:

  • 如果你为它定义一个 Show 实例,你的代码能工作吗?
  • 当然可以。但是,当您可以抱怨 SO 时,为什么还要阅读错误消息呢?
  • GHC 的建议不是一个糟糕、糟糕的想法的罕见案例之一。

标签: haskell tuples


【解决方案1】:

元组可以是任意长度*,但 Show 以及 Eq、Ord、Read、Bounded 等最多只能实例化 15 个元组。来自Haskell 98 report §6.1.4

元组的大小没有上限,但一些 Haskell 实现可能会限制元组的大小,并限制与较大元组关联的实例。 但是,每个 Haskell 实现都必须支持最大 15 大小的元组,以及 Eq、Ord、Bounded、Read 和 Show 的实例。 Prelude 和库定义了元组函数,例如 zip 用于最多大小为 7。

正如其他人所说,如果你需要一个 24 元组,你应该使用更好的数据结构。


编辑:* 从 GHC 6.12.2 开始,元组的最大大小为 62:

Prelude> :t (1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8)

<interactive>:1:0:
    A 64-tuple is too large for GHC
      (max size is 62)
      Workaround: use nested tuples or define a data type

【讨论】:

  • 我相信 GHC 将元组限制为 60 多个元素,但语言标准没有。无论哪种方式,拥有这么大的元组都是愚蠢的:)
【解决方案2】:

在 Haskellers 中很遗憾,元组不是组合的。因此,必须在每个大小的元组上定义任何类型类。我认为报告说实例只需要定义到 10ples 或类似的东西。

在实践中我从不使用超过三倍的。如果您使用元组来执行某种类型级别的逻辑,请构建一个组合变体并使用它。例如:

infixr 9 :*
data a :* b = a :* !b

那么 5ple 的 Ints 的类型将是:

Int :* Int :* Int :* Int :* Int :* ()

末尾的单元 () 对于类型级别逻辑和严格正确性很重要(您不希望最后一个元素是严格的,而所有其他元素都是惰性的)。

注意声明中的 bang。这意味着一个元组的右边是严格的,这样像上面的 5ple 这样的类型可以被扁平化成一个单独的内存块,这样后面的元素就不会比前面的元素更昂贵。

【讨论】:

  • 您的(:*) 将非常适合实施我的准报价器。引用者需要具有任意大的元组(取决于用户)来携带来自返回各种类型的视图模式的返回信息。比嵌套元组好得多。
  • 但是 (a :* b) :* c 与 a :* (b :* c) 不同,对吧?那么除了符号和严格性之外,它与嵌套元组相同吗?
【解决方案3】:

您可以构造更大的元组,但您需要自己定义它们。其次,您没有 Show 实例,因此您还需要为此编写一个实例。

一般来说,当您应该使用更智能的数据类型(例如向量)时,使用大型元组是个坏主意。我们通过限制默认提供的大小来阻止使用。

【讨论】:

    猜你喜欢
    • 2016-02-11
    • 2023-04-02
    • 2012-05-13
    • 2011-10-24
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    相关资源
    最近更新 更多