2013-03-26 52 views
0
(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作爲參數,並返回一個將地圖作爲參數的函數。習慣使用情況FUNC返回一個FUNC

上面的函數還可以將所有三個函數和地圖作爲參數。因此,在這種情況下,不需要創建一個可以返回另一個func的函數。什麼是需要的情況。或者換句話說,引入一個返回函數的函數的慣用模式是什麼?

回答

1

所示的例子可以通過使用部分函數應用程序來實現,以防函數將地圖也作爲參數。

基本上,返回函數的函數是部分應用程序的一個特定情況,即您不會將所有參數傳遞給一個函數,並且返回一個函數,該函數將獲取剩餘的參數並執行原始函數。我個人喜歡使用partial使用部分應用程序或使用匿名函數創建部分功能(例如:#(map inc %))。

爲什麼我們需要它們?有一件事情,當你使用函數組合編程時,它們充當膠水。例如:

您想編寫一個函數,用於遞增向量中的每個數字,然後將其反向。

你可以把它寫無功能組成:

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

使用功能組成:

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

這可能不是最好的例子,但我希望你的想法。

另一個例子可能是包裝函數。他們把輸入作爲一個函數並返回另一個函數(這需要與原始數據相同的參數數量),並在執行原始函數之前或之後執行某些操作(例如:Ring中間件)

1

我同意上面的回覆partial 。然後是comp,它將多個fn作爲輸入,並將它們的組合作爲輸出返回。

下面是一個可能有所幫助的例子,雖然輸出結果不是很明顯。我想要有後臺線程定期重複執行一些任務。每個後臺線程執行一個特定的任務,但任務因線程不同而不同。所以有一個HOF是有意義的,它使用一個代表任務的fn來重複並返回一個線程,在線程中不斷創建執行輸入fn的線程。輸入fn通過包裝在repeatedly表單中而在線程內部不停地執行。

partial是其中輸入和輸出都是單個fn的HOF的最可能方式。我給出的例子是當輸入fn僅用於其副作用時發生的情況,所以如果HOF完全有輸出,那麼HOF的輸出就不是fn。

相關問題