Исходя из ответа, данного Саймоном Марлоу, приведена версия последовательности, которая позволяет избежать утечки пространства, в то же время работая так же, как оригинал, включая сохранение порядка.
Он по-прежнему использует простое понимание списка оригинальной последовательности - единственное отличие состоит в том, что введена ложная зависимость от данных, которая препятствует совместному использованию рекурсивного вызова.
sequenceDummy d [] = d `seq` [[]]
sequenceDummy _ (xs:xss) = [ y:ys | y <- xs, ys <- sequenceDummy (Just y) xss ]
sequenceUnshared = sequenceDummy Nothing
Я думаю, что это лучший способ избежать совместного использования, которое приводит к утечке пространства.
Я бы обвинял чрезмерное разделение в преобразовании "полной лени". Обычно это делает большую работу по созданию совместного использования, которое позволяет избежать повторных вычислений, но иногда повторное вычисление намного более эффективно, чем сохранение общих результатов.
Было бы неплохо, если бы был более прямой способ сказать компилятору не делиться определенным выражением - приведенный выше фиктивный аргумент Maybe
работает и эффективен, но в основном это хак, достаточно сложный, чтобы ghc мог не говорите, что нет реальной зависимости. (На строгом языке у вас нет этих проблем, потому что у вас есть общий доступ, когда вы явно привязываете переменную к значению.)