
Just to be sure, because I am not quite familiar with the dark hairy internals of GHC:
Of course, given a type signature that allows strictness to be inferred.
You mean a signature with no type variables and types that are know to GHC as being strict? (Like Int -> Int -> Int instead of (Num a) => a -> a -> a)
The difference is that the explicit recursion produces the better code even with optimisations turned off, except that the overload of (+) to use is not inlined, so the accumulator still builds a thunk, while with optimisations you get the specialised strict additions (+# resp. plusInteger, ...) so you have the strictness you need.
(+#) is then the GHC's strict equivalent of (+)?
But if you make an overlay to (+), like, say:
(?) :: (Num a) => a -> a -> a
a ? b = a + b
Then (?) will be lazy, won't it?
Then optimizations will not occur, a ? b will remain a thunk and not be
replaced by a +# b and be strictly evaluated?
If so, then it means that you can always turn a strict function into a non
strict one, am I right?
2011/3/31 Daniel Fischer
On Thursday 31 March 2011 11:45:00, Christian Maeder wrote:
Since we don't have a function sum' in the Prelude (should we have it?)
I think we should.
I wonder what happens if you just use "sum". Will the "sum" (based on sum' so without -DUSE_REPORT_PRELUDE) be strict enough?
I don't know about other compiler's behaviour, but for GHC, it will be strict enough *if compiled with optimisations*, but not without (the strictness analyser runs only with optimisations turned on). - Of course, given a type signature that allows strictness to be inferred.
However, the same holds for 'foldl (+) 0'. In fact, in the presence of a suitable type signature, with optimisations turned on, both produce nearly identical code (the order of parameters in the recursive loop is changed, sometimes parameter order can make a surprisingly large difference, but whether it's better to have the list or the accumulator first depends).
The difference is that the explicit recursion produces the better code even with optimisations turned off, except that the overload of (+) to use is not inlined, so the accumulator still builds a thunk, while with optimisations you get the specialised strict additions (+# resp. plusInteger, ...) so you have the strictness you need.
#ifdef USE_REPORT_PRELUDE sum = foldl (+) 0 product = foldl (*) 1 #else sum l = sum' l 0 where sum' [] a = a sum' (x:xs) a = sum' xs (a+x) product l = prod l 1 where prod [] a = a prod (x:xs) a = prod xs (a*x) #endif
Cheers C.
P.S.
isMultiple a = any ((== 0) . mod a)
For Int (and most other types),
isMultiples a = any ((== 0) . rem a)
will be faster (mod is implemented using rem). However, for checks other than comparisons with 0, one needs to be aware of the differences of rem and mod, the latter does what one would expect, rem can badly surprise the unaware.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe