Following hot on the heels of this astonishing header from Boost, here are some excerpts from the module defining tuples in the Glasgow Haskell Compiler:

data (,) a b = (,) a b deriving Generic data (,,) a b c = (,,) a b c deriving Generic

(If you can’t read Haskell: `(,) a b`

is another notation for `(a, b)`

. This defines types for two- and three-element tuples, with a default implementation of the `Generic`

interface.) Okay so far? The file proceeds to define 4-tuples, 5-tuples, and so on until we get to the 8-tuple definition:

data (,,,,,,,) a b c d e f g h = (,,,,,,,) a b c d e f g h -- deriving Generic

Surprise commented-out `deriving`

clause! But it’s all plain sailing from here… until we get to 63-tuples:

data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__ = (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__ -- deriving Generic {- Manuel says: Including one more declaration gives a segmentation fault. data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__ k__ = (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__ k__

…followed by commented-out definitions of everything up to 100-tuples.

## 6 comments ↓

Nicolas Trangezon 03.29.12 at 10:38 pmWould you have any suggestions for another (less ‘verbose’) implementation? This might look somewhat stupid, but it’s the most obvious way as well IMO…

Will Thompsonon 03.30.12 at 7:00 amNo—I don’t think there’s anything wrong with writing out 100 tuple definitions longhand. The bits I think are surprising/funny are the inconsistencies shown in the second and third code blocks (and the commented out standalone

`deriving`

statements for every tuple type, which I didn’t mention in the post).Nicolas Trangezon 03.30.12 at 8:55 amI assumed the removal of Generic deriving for large tuples would be caused by GHC not being able to derive these instances within reasonable space/time constraints.

Looks to be the case indeed:

7fcfc880853fa399c9468049aeb14e6eadb9eae5 Don’t derive Generic for tuples for now

It causes GHC to use vast amounts of space compiling GHC/Tuple.hs.

https://github.com/ghc/packages-ghc-prim/commit/7fcfc880853fa399c9468049aeb14e6eadb9eae5

Ole Laursenon 03.30.12 at 1:19 pmThe works-up-to-n-elements thing reminds me of my college days where I was helping a fellow group of students with a programming assignment for a programming 101 course (with SML). They were all on the math line, not the comp. sci line, and so had chosen an assignment to build a basic library for representing matrices and doing linear algebra. They couldn’t quite figure out how to get the data structure right.

When I gave a (recursive) hint that finally made them realize it was much simpler than they’d thought, one of them said triumphantly: “Hah, but how do you represent an infinite-size matrix with that!”

Ron 04.01.12 at 9:50 amA more expressive notation system (that does not allow to define infix operators) could solve this. In Coq, we can write the following:

Inductive prod (A B:Type) : Type :=

pair : A -> B -> prod A B.

Notation “( x , y , .. , z )” := (pair .. (pair x y) .. z).

Ron 04.01.12 at 9:51 am> that does not allow to define infix operators

that does not ONLY allow to define infix operators