[Haskell-cafe] Re: A problem with par and modules boundaries...
mblazevic at stilo.com
Sat May 23 18:56:25 EDT 2009
On Sat 23/05/09 4:15 PM , Alexander Dunlap alexander.dunlap at gmail.com sent:
>>> Does anybody know of a pragma or another way to make a
>>> function *non-strict* even if it does always evaluate its
>>> argument? In other words, is there a way to
>>> selectively disable the strictness optimization?
>> parallelize a b | False = (undefined, undefined)
>> | otherwise = a `par` (b `pseq` (a, b))
>> might do, unless strictness analysis is smart enough to
>> know that the False guard is always, well, False.
It's GHC.Exts.lazy nowadays, and it doesn't have any effect. Neither
does the `| False' guard. The only way I found to disable the eager
argument evaluation is to pass them in as functions:
> parallelize :: Num t => (t -> a) -> (t -> b) -> (a, b)
> parallelize a b = let a' = a 1
> b' = b 1
> in (a' `par` (b' `pseq` (a', b')))
Then it can be imported and called like this:
> test n1 n2 = let (p1, p2) = parallelize
> (\n0-> product $ factors $ product [n0..n1])
> (\n0-> product $ factors $ product [n0..n2])
This solution is incredibly fragile. If the declared type of parallelize
is modified by replacing t by Integer, the evaluation becomes eager again.
Also, the argument functions can't simply take () for argument which
would make this solution reasonable.
If this is all the strictness optimizer's fault, I'm awed by how
difficult it is to trick it into not doing its job.
More information about the Haskell-Cafe