CONLIKE
Roman Leshchinskiy
rl at cse.unsw.edu.au
Mon Nov 2 17:58:58 EST 2009
On 03/11/2009, at 03:37, Simon Peyton-Jones wrote:
> Roman, Manuel [ccing cvs-ghc for interest]
>
> Consider this:
>
> let xs = build g
> in map (\y. ...(foldr k z xs)...) ys
>
> The foldr/build rule doesn't fire, because in principle it might
> take lots of work to construct the list 'xs'. By doing it outside
> the 'let' we share all the computation of producing xs across every
> element of ys. But in exchange we allocate xs, and retain it.
>
> A common case is when xs started life as [p..q]. For example
>
> f x y = length [(a,b) | a <- [1..x], b <- [1..y]]
>
> Then you might reasonably argue that it's cheaper to reconstruct xs
> for every y, rather than to share it. By the time we've done a bit
> of inlining we get
>
> let g = \cn. eftIntFB c n p q
> xs = build g
> in ...as before...
>
> In short, we'd like to treat (build g) as CONLIKE, *for this
> particular g*. Not for all g's. You can see this by just inlining
> build in your head to get
> xs = g (:) []
> Now if g was CONLIKE we'd be away!
I think you can do this by having two different versions of build: the
normal one and a CONLIKE one. In enumFromTo you'd use build_conlike
(for Int, at least) whereas for expensive computations you'd use build
as before.
> Somehow we'd like to say
>
> build is CONLIKE if its argument is CONLIKE
>
> Or possibly
>
> when trying to decide if (build g) is CONLIKE
> inline 'build' and see if the result is CONLIKE
>
>
> I wondered whether you've encountered this anywhere in NDP? Or
> generally whether it rings any bells.
I vaguely remember thinking about something like this at some point
but I think this is getting far too complex. If we really need this,
I'd much rather implement some form of conditions in rules and write
something like this:
forall g | isConlike g . build g = build_conlike g
Roman
More information about the Cvs-ghc
mailing list