Предел размера кортежа Haskell

Почему я не могу создать большие кортежи в 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
18
задан Ming-Tang 4 June 2010 в 23:27
поделиться

3 ответа

Кортежи могут быть произвольной длины*, но Show, а также Eq, Ord, Read, Bounded и т.д. инстанцируются только до 15 кортежей. Из отчета Haskell 98 §6.1.4:

Не существует верхней границы на размер кортежа, но некоторые реализации Haskell могут ограничивать размер кортежей и ограничивать экземпляры, связанные с большими кортежами. Однако каждая реализация Haskell должна поддерживать кортежи размером до 15, вместе с экземплярами для Eq, Ord, Bounded, Read и Show. Прелюдия и библиотеки определяют функции кортежей, такие как zip, для кортежей размером до 7.

Как говорили другие, если вам нужен кортеж размером 24, вам следует использовать лучшую структуру данных.


Edit: * начиная с 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
22
ответ дан 30 November 2019 в 06:09
поделиться

Вы можете создавать более крупные кортежи, но вам придется определять их самостоятельно. Во-вторых, у вас нет экземпляра Show, поэтому вам также придется написать экземпляр для этого.

В целом, это плохая идея использовать большие кортежи, когда лучше использовать более умный тип данных, например, вектор. Мы препятствуем такому использованию, ограничивая размер, предоставляемый по умолчанию.

11
ответ дан 30 November 2019 в 06:09
поделиться

Многие причитали хаскеллерам, что кортежи не являются композиционными. Таким образом, любой класс типов должен быть определен для каждого размера кортежа. Я думаю, что в отчете говорится, что экземпляры нужно определять только до 10 элементов или что-то в этом роде.

На практике я никогда не использую больше тройки. Если вы используете кортежи для выполнения какой-то логики на уровне типов, создайте композиционный вариант и используйте его вместо этого. Например:

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

Тогда тип пятерки Ints будет следующим:

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

Единица () в конце важна для логики уровня типа, а также для правильности строгости (вы бы не стали хотите, чтобы последний элемент был строгим, а все остальные - ленивыми).

Обратите внимание на взрыв в объявлении. Это означает, что правая часть кортежа является строгой, так что тип, подобный приведенному выше 5ple, может быть сведен к единому фрагменту памяти, чтобы последующие элементы не были более дорогими для доступа, чем более ранние.

23
ответ дан 30 November 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: