0

我们可以看到我们可以使用reduce/foldl1作为函数,通过它我们可以定义其他高阶函数,例如 map、filter 和 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。这里是来自Rich Hickey在 17:25map的Transducers 演讲。filterfoldr

(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 - 关于 fold 的普遍性和表现力的教程 - 1999 http://www.cs.nott.ac.uk/~gmh/fold.pdf

这周我听到有人说:

Well 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 已经根据 map 进行了定义。如果您查看mapcat 的源代码- 我们会看到类似以下内容:

(defn mapcat
  [f & colls]
    (apply concat (apply map f colls)))

所以上面的例子只是颠倒了 concat 并重用了 mapcat 内部的 map 的底层定义——这对我来说是人为的。现在如果可以使用 mapcat 来定义其他 HOF 就可以了——但我不知道该怎么做——我希望有人能指出我的方向。

我的问题是:flatmap/mapcat 是一个可以用作其他高阶函数基础的函数吗?

4

1 回答 1

0

map是用于创建的原语mapcat

您可以使用它mapcat来创建map还原mapcatmap它的构建源。

您可以使用两者来构建无限数量的高阶函数。

于 2014-09-28T13:25:48.563 回答