Fusion vs. inlining (Was: [Haskell-cafe] Fusion of lists and chunky sequences)

Henning Thielemann lemming at henning-thielemann.de
Mon Jan 7 06:36:39 EST 2008

On Thu, 3 Jan 2008, Don Stewart wrote:

> You can, with some caveats, use a single fusion system across data
> structures, and avoid the built in build/foldr system.
> I'd start by installing the stream-fusion list library, from hackage,
> which gives you the list api, and a fusion mechanism.
> To avoid the build in fusion system, you need to:

With 'build in' you mean the fusion system of Prelude?

>     * avoid list comprehensions
>     * avoid .. (use Stream.enumFromTo instead)

No problem.

> then you can write fusion rules for your structure in terms of streams,
> and they'll fuse with list operations as well.

But then in order to fuse your streams with my chunky sequences I have to
know, how stream-fusion fuses streams, right?

Anyway, I tried to wrap Prelude lists in a newtype and thus got GHC (still
6.4.1) to invoke my rules instead of the Prelude rules. But I encountered
the following problem: I define something like

  nonFusable x y = fusable (aux x y)

 where fusion rules are defined for 'fusable', but not for 'nonFusable'. I
hoped that 'nonFusable' will be inlined and then 'fusable' is fused with
other expressions. This does not happen. If I state the function
definition also as rule, then GHC fuses eagerly.
 Analogously I observed that usage of ($) and (.) blocks fusion, and when
I add the rules

  "unfold-dollar" forall f x.
     f $ x = f x ;

  "unfold-dot" forall f g.
     f . g  =  \x -> f (g x) ;

 then fusion takes place as expected.

Am I doing something wrong? Do I have to dig into phase control? I
wouldn't like that, since it seems to be too fragile.

More information about the Haskell-Cafe mailing list