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

Luke Andrew luke.haskell-cafe at la.id.au
Fri Feb 22 03:06:45 EST 2008


Felipe Lessa wrote:
> On Thu, Feb 21, 2008 at 8:58 AM, Luke Andrew <luke.haskell-cafe at la.id.au> 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 :)


More information about the Haskell-Cafe mailing list