Re: [Haskell-cafe] Can't seem to get `par` working appropriately with lists

Felipe Lessa wrote:
On Thu, Feb 21, 2008 at 8:58 AM, Luke Andrew
wrote: test2.hs:
import Control.Parallel
fib1 n = if n == 0 then 0 else if n == 1 then 1 else fib1 (n-1) + fib1 (n-2) fib2 n = if n == 0 then 0 else if n == 1 then 1 else fib2 (n-1) + fib2 (n-2) fiblist1 n = [fib1 x| x <- [1..n]] fiblist2 n = [fib2 x| x <- [1..n]]
main = do print $ zipWith (+) (fiblist2 37 `par` fiblist1 37) (fiblist2 37)
Besides what Jules Bean said, note also that 'par' works a bit like 'seq', only evaluating until WHNF. So even if you said
main = let f1 = fiblist1 37 f2 = fiblist2 37 in print $ zipWith (+) (f2 `par` f1) f2
you still wouldn't get what you want. Why? It only evaluates f1 and f2 until it reaches [] or (_:_), and nothing more, it doesn't even try to figure out that f2 is _:_:_:_:···:[] nor it tries to see that f2 is 1:_, but you wanted that the parallel computation went until f2 was 1:1:2:3:···:[].
To do that, force the list (i.e. do a "deep seq"). There's Control.Parallel.Strategies to help you doing this, but if you want to reimplement it, try
force [] = () force (x:xs) = x `seq` force xs
main = let f1 = fiblist1 37 f2 = fiblist2 37 in print $ zipWith (+) (force f2 `par` f1) f2
'par' will try to see that 'force f2' is really (), but to do that 'force' will go all the way down thru the list forcing its spine and its values.
HTH,
Thanks Felipe, works as advertised. Guest I'm going to have to read up on WHNF, I just ignored it after my initial success & hoped it would continue to work. Guess I should have RTFM :)
participants (1)
-
Luke Andrew