[Haskell-cafe] GHC predictability
Don Stewart
dons at galois.com
Tue May 13 16:21:38 EDT 2008
jeff.polakow:
> Hello,
>
> > For example, the natural and naive way to write Andrew's "mean" function
> > doesn't involve tuples at all: simply tail recurse with two accumulator
> > parameters, and compute the mean at the end. GHC's strictness analyser
> > does the right thing with this, so there's no need for seq, $!, or the
> > like. It's about 3 lines of code.
> >
> Is this the code you mean?
>
> meanNat = go 0 0 where
> go s n [] = s / n
> go s n (x:xs) = go (s+x) (n+1) xs
> If so, bang patterns are still required bang patterns in ghc-6.8.2 to run
> in constant memory:
>
> meanNat = go 0 0 where
> go s n [] = s / n
> go !s !n (x:xs) = go (s+x) (n+1) xs
>
> Is there some other way to write it so that ghc will essentially insert
> the bangs for me?
Yes, give a type annotation, constraining 'n' to Int.
meanNat :: [Double] -> Double
meanNat = go 0 0
where
go :: Double -> Int -> [Double] -> Double
go s n [] = s / fromIntegral n
go s n (x:xs) = go (s+x) (n+1) xs
And you get this loop:
M.$wgo :: Double#
-> Int#
-> [Double]
-> Double#
M.$wgo =
\ (ww_smN :: Double#)
(ww1_smR :: Int#)
(w_smT :: [Double]) ->
case w_smT of wild_B1 {
[] -> /## ww_smN (int2Double# ww1_smR);
: x_a9k xs_a9l ->
case x_a9k of wild1_am7 { D# y_am9 ->
M.$wgo (+## ww_smN y_am9) (+# ww1_smR 1) xs_a9l
}
}
Without the annotation you get:
M.$wgo :: Double#
-> Integer
-> [Double]
-> Double
GHC sees through the strictness of I#.
-- Don
More information about the Haskell-Cafe
mailing list