Передача символа как функции в clojure - PullRequest
4 голосов
/ 02 июня 2011

Я изучаю clojure, и я написал небольшую функцию, которая с указанием пути к каталогу возвращает отсортированную карту файлов в порядке убывания в соответствии с их mtimes.Вот оно:

(defn get-sorted-mtimes [dir]      
  (loop [sm (sorted-map-by >)
         lst (for [f (.listFiles (File. dir))]
               (let [k (.lastModified f)
                     v (.getName f)]
                 [k v]))]
    (if (seq lst)
      (recur (assoc sm ((first lst) 0) ((first lst) 1))
        (rest lst))
      sm)))

Мой вопрос: есть ли способ передать метод сравнения в качестве имени символа в функцию и сделать его сортировку по порядку asc или desc соответственно?Я имею в виду что-то вроде:

(defn get-sorted-mtimes [dir <sym>]  
  (loop [sm (sorted-map-by <sym>)
       ...

Кроме того, есть ли более сомнительный способ выполнения этой задачи?

Ну, для записи, это последняя форма функции, которая делает именно то, что мне нужно:

(defn get-sorted-mtimes [dir comp]      
  (loop [sm (sorted-map-by (comparator comp))
         lst (for [f (.listFiles (File. dir))]
               (let [k (.lastModified f)
                     v (.getName f)]
                 [k v]))]
    (if (seq lst)
      (recur (assoc sm ((first lst) 0) ((first lst) 1))
        (rest lst))
      sm)))

Если функция (компаратор) не используется,получить исключение java.lang.ClassCastException.

1 Ответ

4 голосов
/ 02 июня 2011

> это просто функция, как и любая другая в Clojure.Так что ничто не мешает вам передать это в качестве аргумента.

На самом деле я бы сказал, что это хороший стиль Clojure, чтобы делать это таким образом.Clojure - это функциональный язык программирования, поэтому нет ничего плохого в том, чтобы использовать функции высшего порядка там, где это необходимо!

Некоторые другие незначительные предложения:

  • Использование comparator вместо <sym> в качестве имени параметра вашей функции.Я думаю, что это более наглядно и более согласуется с обычными соглашениями об именах Clojure.
  • Вы также можете добавить еще один параметр функции, чтобы определить, что вы сравниваете, чтобы можно было передать функцию, такую ​​как get-mtime (простая функциявозвращает время файла).
  • Я бы предложил сделать последовательность файлов для ввода в функцию, а не в каталог.Тогда ваша функция носит более общий характер и может обрабатывать такие вещи, как, например, рекурсивное сканирование каталогов точно таким же образом
  • Я бы предложил использовать (into sm lst) - намного проще, чем ваш большой цикл / конструкция if / recur!

Тогда вы можете делать действительно хорошие вещи, такие как (get-sorted-files (list-files-recursive dir) > get-mtime) - или любые подобные комбинации, которые вы можете придумать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...