4 ms·
I think this is just announcing that the Clojure core libraries are gaining another arity for many functions specifically for this usage so that you don't have
by jzelinskie 12y ago
I think this is just announcing that the Clojure core libraries are gaining another arity for many functions specifically for this usage so that you don't have to use (partial) or the short-hand #() syntax to use this pattern. I assume the goal is more community awareness and cleaner syntax for the re-use of this pattern.
- richhickey 12y agoNo, (map f) is not curried map. It returns an entirely different thing - a function of reducing function to reducing function, aka a reducing function transformer, aka a transducer.
- avernet 12y agoProviding the signature of this new `map` function (e.g. as in Haskell's fmal http://www.haskell.org/hoogle/?hoogle=fmap http://www.haskell.org/hoogle/?hoogle=fmap), would certainly go a long way towards helping people understand what this `map` does.
- richhickey 12y agoThese sigs are for the arities below only. map f: (a->b)->(x->b->x)->(x->a->x) filter pred: (a->bool)->(x->a->x)->(x->a->x) flatmap f: (a->[b])->(x->b->x)->(x->a->x) etc.
- spion 12y agoSo, a transduceMap implementation would be this I guess? transduceMap :: (b -> a) -> (acc -> a -> acc) -> (acc -> b -> acc) transduceMap f = \reduceFn -> \acc el -> reduceFn acc (f el) lambda added for clarity (no pun intended), however types are easier to match when using this syntax: transduceMap :: (b -> a) -> (acc -> a -> acc) -> acc -> b -> acc transduceMap f reduceFn acc el = reduceFn acc (f el)
- avernet 12y agoOK, maybe we're getting somewhere. Let me try to write this `map`, just to see. I'm using Scala, so I can put some types, and have the compiler yell at me if I'm doing something overtly wrong (I need all the help I can get!). For clarity, let's define a type alias for reducers: type Reducer[X, A] = (X, A) ⇒ X Let's define `map` to match the type definition you provided. And with that type definition, I only see one way in which the function can be implemented. So it must be: def map[X, A, B](f: A ⇒ B): (Reducer[X, B] ⇒ Reducer[X, A]) = (redB: Reducer[X, B]) ⇒ (x: X, a: A) ⇒ redB(x, f(a)) How can I use this? Let's try the following: def addup(zero: Int, a: List[Int]) = a.foldLeft(zero)(_ + _) def parseList(a: List[String]) = a.map(_.toInt) map(parseList)(addup)(1, List("7", "8")) This returns 16. OK, parsing the list, and adding up starting from 1. But it doesn't look to me like `map` implements anything like the usual semantic of map. It just converts the data structure, and applies the reducer. What am I missing here?