Что такое Stream Fusion от Haskell

Что такое Stream Fusion в Haskell и как его использовать?

Ответов (3)

Решение

Бумага, на которую указывает Логан, великолепна, но немного сложна. (Просто спросите моих студентов.) Это также много о том, «как работает слияние потоков», и лишь малая доля «что такое слияние потоков и как вы можете его использовать».

Проблема, которую решает объединение потоков, заключается в том, что функциональные коды в том виде, в котором они написаны, часто выделяют промежуточные списки, например, для создания бесконечного списка номеров узлов вы можете написать

nodenames = map ("n"++) $ map show [1..]

Наивный код выделил бы бесконечный список целых чисел [1, 2, 3, ...], бесконечный список строк ["1", "2", "3", ...] и, в конечном итоге, бесконечный список имен ["n1", "n2", "n3", ...] . Это слишком много.

Слияние потоков переводит определение, например, nodenames во что-то, что использует рекурсивную функцию, которая выделяет только то, что необходимо для результата. В общем, устранение промежуточных списков называется вырубкой лесов .

Для использования потока слияния, вы должны написать не-рекурсивные функции списка , которые используют функции из библиотеки поток-фьюжн , описанной в GHC билете 915 ( map, foldr и так далее) вместо явного рекурсии. Эта библиотека содержит новые версии всех функций Prelude, которые были переписаны для использования слияния потоков. Очевидно, этот материал планируется включить в следующий выпуск GHC (6.12), но его нет в текущей стабильной версии (6.10). Если вы хотите использовать библиотеку, у Порджеса есть хорошее простое объяснение в своем ответе.

Если вам действительно нужно объяснение того, как работает слияние потоков, задайте другой вопрос, но это намного сложнее.

Насколько мне известно, и вопреки тому, что сказал Норман, слияние потоков в настоящее время не реализовано в базе GHC (т.е. вы не можете просто использовать функции Prelude). Для получения дополнительной информации см. Билет 915 GHC .

Чтобы использовать слияние потоков, вам необходимо установить библиотеку слияния потоков, импортировать Data.List.Stream (вы также можете импортировать Control.Monad.Stream) и использовать только функции из этого модуля, а не функции Prelude. Это означает, что импорт Prelude скрывает все функции списка по умолчанию, а не использует конструкции [x..y] или понимание списка.

Разве это не правильно, что когда GHC в 6.12 использует эти новые функции по умолчанию, они также будут реализовывать [x..y] и перечислять понимания таким нерекурсивным образом? Потому что единственная причина, по которой они находятся в неправильном ряду, заключается в том, что они являются внутренними и на самом деле написаны не на Haskell, а больше похожи на ключевые слова, ради скорости и / или потому, что вы не сможете переопределить этот синтаксис.