【问题标题】:idiomatic use case for func which returns a funcfunc 的惯用用例,它返回一个 func
【发布时间】:2013-03-16 03:13:27
【问题描述】:
(defn sort-map-by-value
  "Given a map return a sorted map, in which the sort is done on the map's values, instead of keys.
   Takes a function as an input, which will be used  for sorting"
  [cf kf]
  (fn [m]
    (->> m
         map-invert
         (into (sorted-map-by #(cf (kf %1) (kf %2))))
         map-invert)))

(defn date-time-comparator
  "Predicate function for comparing two date-time's"
  [time1 time2]
  (before? time1 time2))

(defn get-time-value
  "Function for extracting the date-time from the value of the given map."
  [v]
  (-> v first :time))

(def sort-map-by-date (sort-map-by-value date-time-comparator get-time-value))

(sort-map-by-date {"3-19-2013" [{:time (date-time 2013 3 19 12 14 45)}]
                         "3-9-2013" [{:time (date-time 2013 3 9 16 46 49)}]
                         "2-25-2013" [{:time (date-time 2013 2 25 2 38 15)}]
                         "3-14-2013" [{:time (date-time 2013 3 14 7 19 23)}]
                         "2-8-2013" [{:time (date-time 2013 2 8 12 44 47)}]
                         })

我试图了解使用高阶函数的惯用模式是什么。专门针对返回函数的函数。第一个函数 sort-map-by-value,以 2 个 fns 作为参数并返回一个以 map 作为参数的函数。

上述函数也可以将这三个函数、2 个函数和地图作为参数。所以在这种情况下不需要创建一个返回另一个函数的函数。需要它的情况是什么。或者换句话说,引入返回函数的函数的惯用模式是什么?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    如果函数将地图也作为参数,则可以使用部分函数应用程序来实现所示示例。

    基本上,返回函数的函数是部分应用的一种特殊情况,即您不会将所有参数传递给函数,而作为回报,您会得到一个函数,该函数将获取剩余的参数并执行原始函数。我个人喜欢使用partial 使用部分应用程序或使用匿名函数来创建部分函数(例如:#(map inc %))。

    为什么我们需要它们?一方面,当您使用函数组合进行编程时,它们充当粘合剂。例如:

    您想编写一个函数,将向量中的每个数字递增,然后将其反转。

    不用函数组合也可以写:

    (defn foo [v]
       (reverse (map inc v)))
    

    使用函数组合:

    (def foo (comp reverse (partial map inc)))
    

    这可能不是最好的例子,但我希望你能明白。

    另一个例子是包装函数。它们将输入作为一个函数并返回另一个函数(与原始函数具有相同数量的参数)并在执行原始函数之前或之后执行某些操作(例如:Ring 中间件)

    【讨论】:

      【解决方案2】:

      我同意之前关于partial 的回复。然后是comp,它将多个 fn 作为输入并将它们的组合作为输出返回。

      这是一个可能有帮助的示例,尽管输出并不完全是 fn。我想让后台线程定期重复执行一些任务。每个后台线程执行一项特定任务,但任务因线程而异。因此,有一个 HOF 是有意义的,它接受一个 fn 表示要重复的任务并返回一个 Thread,其中创建的 Thread 不断执行输入 fn。输入 fn 通过包装在 repeatedly 表单中,在 Thread 内不间断地执行。

      partial 是最有可能的方式,其中输入和输出都是单个 fn 的 HOF。我给出的示例是当输入 fn 仅用于其副作用时会发生什么,因此如果 HOF 有输出,那么 HOF 的输出就没有必要成为 fn。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-10
        • 1970-01-01
        • 2019-03-08
        相关资源
        最近更新 更多