Как я могу сплавить две карты по одному списку?
Мы могли бы сплавить два обхода по списку xs
в выражении
(map f xs, map g xs)
так
unzip (map (\x -> (f x, g x)) xs)
Есть ли какой-либо поиск автоматического выполнения такого рода слияния?
(Здесь существует риск создать утечку пространства, если один из возвращенных списков будет потреблен раньше другого. Меня больше интересует предотвращение дополнительного обхода xs
, чем сохранение пробела.)
Изменить: я на самом деле не пытаюсь применить слияние к фактическим спискам Haskell в памяти, где это преобразование может не иметь смысла в зависимости от того, может ли unzip
соединить его с потребителем. У меня есть настройка, где я знаю, что unzip
может сработать (см. "FlumeJava: простые, эффективные параллельные параллельные потоки данных" ).
Ответы
Ответ 1
Также не полностью автоматический, но вы можете дать GHC список правил перезаписи, подобных этому. См. 7.14 Переписать правила и Использование правил. Затем компилятор использует эти правила для оптимизации вашей программы при компиляции. (Обратите внимание, что компилятор никоим образом не проверяет, имеют ли смысл какие-либо правила.)
Изменить: Чтобы привести пример этой конкретной проблемы, мы можем написать:
{-# OPTIONS_GHC -fenable-rewrite-rules -ddump-rule-firings -ddump-rule-rewrites #-}
import Data.Char
{-# RULES
"map/zip" forall f g xs. (,) (map f xs) (map g xs) = unzip (map (\x -> (f x, g x)) xs)
#-}
main :: IO ()
main = let x = "abCD" in
print $ (,) (map toUpper x) (map toLower x)
(имя функции верхнего уровня в правиле (,) :: a -> b -> (a, b)
). При компиляции вы увидите, как применяются правила. Параметр dump-rule-firings
показывает сообщение, когда применяется правило, и -ddump-rule-rewrites
отображает каждое приложение правила подробно - см. 7.14.6. Контроль выполнения правил перезаписи.
Ответ 2
Мне удалось найти два ресурса, в которых упоминаются функции fusion (un-) zip-like, по крайней мере, кратко:
Йозеф Свеннингссон. "Ярлык Fusion для накапливания параметров и zip-подобных функций"
http://www.cse.chalmers.se/~josefs/publications/fusion.pdf
Дункан Коуттс. "Stream Fusion: практическое сочетание горячих клавиш для типов коиндуктивной последовательности"
https://community.haskell.org/~duncan/thesis.pdf
Ни один из ресурсов не упоминает об этом виде "sibling fusion" явно.