Подтвердить что ты не робот

Ограничение размера пакета 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
4b9b3361

Ответ 1

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

Верхняя граница размера кортежа отсутствует, но некоторые реализации Haskell могут ограничивать размер кортежей и ограничивать экземпляры, связанные с большими кортежами. Однако каждая реализация Haskell должна поддерживать кортежи размером до 15, вместе с экземплярами для Eq, Ord, Bounded, Read и Show. Прелюдия и библиотеки определяют такие функции, как 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

Ответ 2

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

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

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

Тогда тип 5pl из Ints будет:

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

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

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

Ответ 3

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

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