Clojure отложенная функция выполнения

Хорошо Вот что я пытаюсь сделать

(defn addresses [person-id]
 ;addresses-retrival )

(defn person [id]
  (merge  {:addresses (addresses id)} {:name "john"}))

В вышеупомянутой функции person я хочу, чтобы адреса были получены только по требованию, например, только когда я делаю

(:addresses (person 10)) 

, а не когда

(person 10)

Я не уверен, правильно ли я поступаю, будучи новичком в clojure.

12
задан Surya 22 August 2010 в 16:14
поделиться

3 ответа

Вы можете использовать задержку.

(defn person [id]
  (delay  {:addresses (addresses id) :name "john"})) 

(человек 2) затем вернет задержку, ничего не оценивая. Чтобы получить доступ к содержимому и оценить отложенный объект, используйте force или deref (или @).

(:addresses @(person 5))

Как вариант, вы можете установить задержку только по адресу.

(defn person [id]
  {:addresses (delay (addresses id)) :name "john"})

что может быть лучше в зависимости от вашей проблемы.

Это позволяет определить:

(defn get-address [person]
  @(:address person))

Которая получит задержанный адрес и принудительно его обработает. (Принудительное вычисление означает первое вычисление и получение принудительного результата в любое другое время).

10
ответ дан 2 December 2019 в 21:42
поделиться

По крайней мере, в том, что касается последовательностей, clojure чертовски лениво, и не требует дополнительных указаний.

Здесь, моделируя получение адреса как подсчет, попробуйте:

(defn addresses [person-id]
  (iterate #(do (println %) (inc %)) person-id))

(defn person [id]
  (merge  {:addresses (addresses id)} {:name "john"}))

(def people (map person (range 100)))

Пока что ничего не было напечатано, но если вы скажете:

(doall (take 5 (:addresses (nth people 10))))

Тогда вы должны увидеть, что печать происходит именно в тех случаях, когда это необходимо. приходится считать пять на десятом месте. Я полагаю, что это может быть именно то поведение, которое вы хотите?

Так что заставьте ваш поиск адреса производить ленивую последовательность (карта, фильтр, сокращение - все подойдет)

1
ответ дан 2 December 2019 в 21:42
поделиться

Я могу предложить что-то близкое к тому, что вы ожидаете.

; Note the use of anonymouns function. #(addresses id)
(defn person [id] 
  (merge  {:addresses #(addresses id)} {:name "john"}))

; :addresses returns a function. Evaluate it by wrapping it in another set of parans.
((:addresses (person 10)))
0
ответ дан 2 December 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: