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