【问题标题】:Is flatmap/mapcat a function that can be used as the basis of other higher order functions?flatmap/mapcat 是不是可以作为其他高阶函数基础的函数?
【发布时间】: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 做到这一点。这里是 mapfilter,在 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


    【解决方案1】:

    map 是用于创建mapcat 的原语。

    您可以使用mapcat 创建map,这会将mapcat 还原为构建它的map

    您可以使用这两种方法构建无限数量的高阶函数。

    【讨论】:

    • 谢谢!你能举一个构建 HOF 的例子吗?
    • 每一个以函数为参数的函数都是高阶函数。
    猜你喜欢
    • 2022-07-15
    • 1970-01-01
    • 2019-08-27
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    相关资源
    最近更新 更多