开发者

Haskell Tuple Size Limit

开发者 https://www.devze.com 2023-01-02 14:21 出处:网络
Why I can\'t construct large tuples in Haskell? Why there\'s a tuple size limit? 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)

Why I can't construct large tuples in Haskell? Why there's a tuple size limit?

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 st开发者_如何学Pythonmt of a 'do' expression: print it


Tuples can be of arbitrary length*, but Show, as well as Eq, Ord, Read, Bounded, etc are only instantiated up to 15-tuple. From the Haskell 98 report §6.1.4:

There is no upper bound on the size of a tuple, but some Haskell implementations may restrict the size of tuples, and limit the instances associated with larger tuples. However, every Haskell implementation must support tuples up to size 15, together with the instances for Eq, Ord, Bounded, Read, and Show. The Prelude and libraries define tuple functions such as zip for tuples up to a size of 7.

As others have said, if you need a 24-tuple, you should use a better data structure.


Edit: * as of GHC 6.12.2, the maximum size of a tuple is 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


Much lamented among Haskellers, tuples are not compositional. So any typeclass must be defined on every size of tuple. I think the report says that instances only need to be defined up to 10ples or something like that.

I never use more than a triple in practice. If you are using tuples to do some kind of type-level logic, build a compositional variant and use that instead. For example:

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

Then the type of a 5ple of Ints would be:

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

The unit () at the end is important for type level logic as well as for strictness correctness (you wouldn't want the last element to be strict and all the others to be lazy).

Note the bang in the declaration. It means that the right side of a tuple is strict, so that a type like the above 5ple can be flattened down into a single chunk of memory, so that later elements are not more expensive to access than earlier ones.


You can construct larger tuples, but you'll need to define them yourself. Secondly, you don't have a Show instance, so you would also need to write an instance for that.

In general, it is a bad idea to use large tuples, when you should be using a smarter data type, such as a vector. We discourage the use by limiting the size provided by default.

0

精彩评论

暂无评论...
验证码 换一张
取 消