[Haskell-cafe] ANN: HLint 1.2

Robin Green greenrd at greenrd.org
Mon Jan 12 12:06:05 EST 2009


On Mon, 12 Jan 2009 19:43:00 +0100
"Bas van Dijk" <v.dijk.bas at gmail.com> wrote:

> On Mon, Jan 12, 2009 at 6:47 PM, Max Bolingbroke
> <batterseapower at hotmail.com> wrote:
> > GHC should indeed be doing so. I'm working (on and off) to work out
> > some suitable heuristics and put the transformation into ghc -O2.
> > There are a few wrinkles that still need sorting out, but
> > preliminary indications are that it decreases the runtime of our
> > standard benchmark suite, nofib, by 12% or so.
> 
> Great!
> 
> In the Stream library I'm developing at http://code.haskell.org/Stream
> I 'closurize' (for lack of a better name) all my functions. Here are a
> few random examples:
> 
> repeat :: a -> Stream a
> repeat x = repeat_x
>     where
>       repeat_x = x ::: repeat_x
> 
> cycle :: [a] -> Stream a
> cycle xs = cycle_xs
>     where
>       cycle_xs = foldr (:::) cycle_xs xs
> 
> deleteBy :: (a -> a -> Bool) -> a -> Stream a -> Stream a
> deleteBy eq x = deleteBy_eq_x
>     where
>       deleteBy_eq_x (y ::: ys)
>           | eq x y    = ys
>           | otherwise = y ::: deleteBy_eq_x ys
> 
> Closurizing the functions in Data.Stream lead to 10% to 250% speedups!

Awesome!

I tend to use Control.Monad.Fix.fix (which actually has nothing to do
with monads, despite the package name) sometimes, for "closurizing" a
recursive function. I am curious as to whether the "fix" style of
recursive programming is likely to result in the same speedups.

The fix-style equivalent to your repeat above, would be something like
this:

repeat x = fix $ \me -> x ::: me

(I use "me" for the name of the recursive call, partly because it
reminds me that it's a self-call, and partly because I find it amusing)

-- 
Robin


More information about the Haskell-Cafe mailing list