Ответ 1
Да, см. параллельный пакет:
ls `using` parList rdeepseq
будет оценивать каждый элемент списка параллельно с помощью стратегии rdeepseq
. Обратите внимание, что использование parListChunk
с хорошим значением куска может дать лучшую производительность, если ваши элементы слишком дешевы, чтобы получить преимущество, оценивающее каждую из них параллельно (потому что оно экономит на искрообразовании для каждого элемента).
РЕДАКТИРОВАТЬ: Основываясь на вашем вопросе, я чувствую, что должен объяснить, почему это ответ. Это потому, что Хаскелл ленив! Рассмотрим утверждение
let bs = map expensiveFunction as
Ничего не было оценено. Вы только что создали thunk, который отображает expensiveFunction
. Итак, как мы оцениваем его параллельно?
let bs = map expensiveFunction as
cs = bs `using` parList rdeepseq
Теперь не используйте список bs
в своих будущих вычислениях, вместо этого используйте список cs
. IOW, вам не нужна параллельная карта, вы можете использовать обычные (ленивые) карты и стратегию параллельной эвакуации.
EDIT: И если вы посмотрите достаточно, вы увидите функцию parMap, которая сделает то, что я показал здесь, но обернута в одну вспомогательную функцию.
В ответ на ваш комментарий код ниже не работает для вас? он работает для меня.
import Control.Parallel.Strategies
func as =
let bs = map (+1) as
cs = bs `using` parList rdeepseq
in cs