Lets take fusion as an example:
- this fuses
@List.fmap #f /Y #fmap #xs #c #n
//xs
#x #xs //c /f x /fmap xs
n
- this does not
@List.map #f /Y #map #xs
//xs
#x #xs #c #n //c /f x /map xs
#c #n n
Obviously it is not possible to transform map to fmap, unless we know that xs is well behaved. (Bad behaved xs would be for example #con #nil #x x.)
Now comes the tough question? How do we know xs is well behaved?
- In pure lambda calculus it's impossible. You have to do it by hand.
- Adding annotations or constructors is interesting middle ground. For example Haskell has ADT and pattern matching which allows this particular transformation.
- Type system (the more powerful the better) is the general solution. Since nobody has done it (AFAIK), it won't be trivial.
Can it be done?