2013-03-26 2 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

Вышеупомянутая функция также может принимать все три, 2 funcs и карту в качестве параметра. Поэтому нет необходимости создавать функцию, которая в этом случае возвращает другую функцию. Какой будет случай, когда это будет необходимо. Или, другими словами, что такое идиоматический шаблон для введения функции, которая возвращает функцию?

ответ

1

Показанный пример мог быть достигнут с помощью приложения частичной функции, если функция приняла карту также как параметр.

В принципе, функция, возвращающая функцию, является конкретным случаем частичного приложения, то есть вы не передаете все параметры функции, а взамен получаете функцию, которая будет принимать оставшиеся параметры и выполнять исходную функцию. Мне лично нравится использовать частичное приложение, используя partial или используя анонимные функции для создания частичных функций (например: #(map inc %)).

Для чего они нужны? Во-первых, они действуют как клей, когда вы программируете с использованием композиции функций. Например:

Вы хотите написать функцию, которая увеличивает каждое число в векторе и затем меняет его.

Вы можете написать его без функции композиции:

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

Использование функции состава:

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

Это может быть не лучший пример, но я надеюсь, что вы получите эту идею.

Другим примером могут быть функции обертки. Они берут ввод как функцию и возвращают другую функцию (которая принимает такое же количество параметров, что и исходное), и делают что-то до или после выполнения исходной функции (например: промежуточное ПО для звонков)

1

Я согласен с предыдущим ответом о partial , И тогда есть comp, который принимает несколько фн в качестве входных данных и возвращает их состав в качестве вывода.

Вот пример, который может помочь, хотя выход не совсем fn. Я хотел бы, чтобы фоновые потоки неоднократно выполняли некоторые задачи через регулярные промежутки времени. Каждый фоновый поток выполняет одну конкретную задачу, но задача отличается от одного потока к другому. Поэтому имеет смысл иметь HOF, который принимает fn, представляющий задачу, чтобы повторять и возвращает Thread, где создается поток, который непрерывно выполняет вход fn. Входной сигнал fn выполнен для выполнения без остановки внутри резьбы путем обертывания в форме repeatedly.

partial - наиболее вероятный способ, при котором HOF, где вход и выход являются как одиночными fn каждый. Пример, который я дал, - это то, что происходит, когда вход fn необходим только для его побочных эффектов, поэтому нет смысла, чтобы выход HOF был fn, если HOF имеет выход вообще.

Смежные вопросы