"The reduce function is the base transformation; any other transformation can be expressed in terms of it (map, filter, etc)."
This seems so obvious in retrospect -- I can't believe I had never made that connection before.
For JS, I personally prefer lo-dash for this kind of work, or dropping in polyfills from MDN.
For some context, here are .map functions applied to normal arrays http://jsperf.com/native-vs-array-js-vs-underscore/54
I've been looking for similar libraries that work on typed-arrays because they are so much more efficient when working with web-workers or with raw canvas data. My attempts at hacking it in feel like they are just bad ideas: http://jsperf.com/float32array-map/2
When you reduce with function f(T1, T2) -> T3 the result of previous iteration becomes first argument for the next iteration, so they must be of the same "type".
Or am I missing something?
I was thinking that mapping can be f(T1)->T2 and how reducing can change types too, but I guess I wasn't paying enough attention because of course the reduce signature is f(accumulator, input) and the output is accumulator, so yea, you're absolutely right: f(T1,T2)->T1
-- Mogensen-Scott encoding
data ScottList a = ScottList (forall r. (a -> ScottList a -> r) -> r -> r)
-- Boehm-Berarducci encoding
data ChurchList a = ChurchList (forall r. (a -> r -> r) -> r -> r)
Roughly, the first encoding gives you pattern matching, and the second gives you foldr (reduce). Either of these operations is sufficient to do anything with the list.Also note that both of these are encodings of lazy (potentially infinite) lists. To encode strict (guaranteed finite) lists, you really need algebraic data types like in ML, the visitor pattern can't do that.
[0] Graham Hutton, "A tutorial on the universality and expressiveness of fold", J. Functional Programming 9(4): 355–372, July 1999. http://www.cs.nott.ac.uk/~gmh/fold.pdf
(Shameless plug in the hope it may be helpful to someone)
[1]: http://simplectic.com/blog/2014/transducers-explained-1/