У меня есть список n-битных "слов"
type BitWord = [Bool]
и дерево, в котором хранится слово сверху вниз:
data Tree = Bs Tree Tree -- Bs (zero_bit) (one_bit)
| X -- incomplete word
| B -- final bit of word
У меня есть функция:
seenPreviously :: BitWord -> Tree -> (Tree,Bool)
Функция перебирает биты в BitWord
, спускаясь по Tree
влево с нулевым битом и наоборот. Мы возвращаем новое дерево с этим BitWord
«объединенным» вместе с True, если нам нужно было добавить поддеревья в какой-то момент (т. Е. BitWord
еще не было в дереве), и False в противном случае.
Я отображаю эту функцию на [BitWord]
, передавая дерево как состояние.
У меня такой вопрос : может ли это быть полезным от параллелизма, предлагаемого Control.Parallel? И если да, то как я могу рассуждать о лени и оценке только слабой головы нормальной формы и т. Д .?
Мой инстинкт состоит в том, что я могу вставлять (фактически создавая поддерево) в левую ветвь, делая то же самое в правой ветви, как два независимых потока. Что-то вроде:
parallelMapSt :: [ BitWords ] -> Tree -> [Bool]
parallelMapSt [] _ = []
parallelMapSt (w:ws) t = let (b,t') = seenPreviously w t
bs = parralelMapSt ws t'
in t' `par` bs `pseq` (b:bs)
Поток, оценивающий b
, зависит от некоторых ранее запущенных потоков (принадлежащих BitWords
, которые имеют общий префикс с w
), но не от всех, так что может показаться, что есть возможность работать параллельно здесь, но я действительно не уверен.