Change the representation of optimized list of operation and add folding.

After optimization, an operation is a list of flatmap and something at the end, so I changed it to be actually that. It makes the representation cleaner imho and migth be usefull for, let's say, implement a ParMap version.
We could merge flatmaps at the end, I'm not sure how usefull it is. Did you benched that ?

I also added folding.

I didn't updated benchmarks with the removal of the optimization level.