【发布时间】:2014-11-22 19:03:05
【问题描述】:
我们可以看到我们可以使用reduce/foldl1作为we can define other higher order functions such as map, filter and reverse的函数。
(defn mapl [f coll]
(reduce (fn [r x] (conj r (f x)))
[] coll))
(defn filterl [pred coll]
(reduce (fn [r x] (if (pred x) (conj r x) r))
[] coll))
(defn mapcatl [f coll]
(reduce (fn [r x] (reduce conj r (f x)))
[] coll))
我们似乎也可以通过foldr 做到这一点。这里是 map 和 filter,在 17:25 时是 foldr from Rich Hickey's Transducers talk。
(defn mapr [f coll]
(foldr (fn [x r] (cons (f x) r))
() coll))
(defn filterr [pred coll]
(foldr (fn [x r] (if (pred x) (cons x r) r))
() coll))
现在发现有一些论文可以解释这一点:
BIRD - 构造函数式编程讲座 - 1988 https://www.cs.ox.ac.uk/files/3390/PRG69.pdf
HUTTON - 关于折叠的普遍性和表现力的教程 - 1999 http://www.cs.nott.ac.uk/~gmh/fold.pdf
这周我听到有人说:
flatmap(mapcat) 是基本的——你可以用它来表达很多高阶函数。
所以这里是 map 根据 mapcat 实现的。
=> (defn mymap [f coll] (mapcat (comp vector f) coll))
=> (mymap #(+ 1 %) (range 0 9))
(1 2 3 4 5 6 7 8 9)
但对我来说,这感觉是做作的,因为您实际上只是在对事物进行拳击并确定地图本身是否“基本”。
最后一个例子感觉有点人为的原因是 mapcat 已经根据地图进行了定义。如果您查看source for mapcat - 我们会看到类似于:
(defn mapcat
[f & colls]
(apply concat (apply map f colls)))
所以上面的例子只是颠倒了 concat 并重用了 mapcat 内部的 map 的底层定义——这对我来说是人为的。现在如果可以使用 mapcat 来定义其他 HOF 就可以了——但我不知道该怎么做——我希望有人能指出我的方向。
我的问题是:flatmap/mapcat 是不是可以作为其他高阶函数基础的函数?
【问题讨论】:
标签: map clojure fold higher-order-functions flatmap