用于返回func的func的惯用用例

时间:2013-03-26 10:49:00

标签: clojure

(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个函数和地图作为参数。因此,在这种情况下,不需要创建一个返回另一个函数的函数。会是什么情况需要它。或者换句话说,引入一个返回函数的函数的惯用模式是什么?

2 个答案:

答案 0 :(得分:1)

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

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

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

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

你可以在没有功能组合的情况下编写它:

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

使用功能组合:

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

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

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

答案 1 :(得分:1)

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

这里有一个可能会有所帮助的例子,虽然输出不是fn。我想让后台线程以固定间隔重复执行某些任务。每个后台线程执行一个特定任务,但任务因线程而异。因此,有一个HOF可以使fn代表任务重复并返回一个Thread,其中Thread被创建,不断执行输入fn。输入fn通过以repeatedly形式包装而在Thread内部执行不间断。

partial是输入和输出均为单个fn的HOF最可能的方式。我给出的例子是当输入fn只需要它的副作用时会发生什么,所以如果HOF根本没有输出,那么HOF的输出就没有必要成为fn。