Hacker News new | past | comments | ask | show | jobs | submit login

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.



No, (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.


Providing the signature of this new `map` function (e.g. as in Haskell's fmal http://www.haskell.org/hoogle/?hoogle=fmap), would certainly go a long way towards helping people understand what this `map` does.


These 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.


OK, 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?


So, 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)




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: