Proposal: Add strict iterate' (and a discussion of possible new RULES)
David Feuer
david.feuer at gmail.com
Wed Jul 30 16:30:16 UTC 2014
I'm pushing hard to get unfoldr fixed ASAP, and looking to take
advantage of that. Specifically, I like the idea of using the fusion
that (I dearly hope) will come with unfoldr to make a variety of other
things fuse that currently need their own special rules. I also want
to extend fusion by one or two general rules. One that looks very good
is similar to the rejected foldr/cons rule, but seems somewhat less
likely to cause problems while still enhancing fusion in general:
{-# RULES
"cons/build" forall x (g::forall b . (a->b->b)->b->b) . x : build g =
build (\c n -> x `c` g c n)
#-}
This will allow foldr/build fusion to look past conses. So for example,
foldr f q (x : build g)
will be rewritten (cons/build) to
foldr f q (build (\c n -> x `c` g c n))
and then (fold/build) to
(\c n -> x `c` g c n) f q
This reduces to
f x (g f q)
A discussion about foldr k z (x1:x2:x3:...:x2000:build g), a possible
way to fix it, and why I don't think it's important anyway.
This means the same thing as
foldr k z ([x1,x2,x3,...,x2000] ++ build g)
The current ++ rule rewrites this to
foldr k z (augment (\c n -> foldr c n [x1,...,x2000]) (build g))
Then foldr/augment:
(\c n -> foldr c n [x1,..,x2000]) k (foldr k z (build g))
Then foldr/build:
(\c n -> foldr c n [x1,...,x2000]) k (g k z)
Then beta reduction:
foldr k (g k z) [x1,...,x2000]
So to take the example from earlier,
foldr f q (x : build g)
is currently bad, but
foldr f q ([x] ++ build g)
will end up
foldr f (g f q) [x]
and then in this case the foldr/single rule will give
f x (g f q)
but if more than one element were in the list, we'd end up with a fold
over the literal list (not bad in general).
This suggests a fix, but one that may be difficult to implement within
GHCs stage framework as is (I'm not quite sure; someone who knows more
about the system may see a way to do this, but I think it wants to
happen before the ++ rule, which I think happens at the beginning of
time):
Translate x1:x2:x3:...:build g to [x1,x2,x3,...] ++ build g
Then let everything else happen as usual.
I think, however, that this is probably overkill. Just implement
cons/build and tell users that if they want x1:x2:x3:....:x2000:foo
not to expand under foldr then they need to write
[x1,x2,x3,...,x2000]++foo instead.
More information about the Libraries
mailing list