построить набор лениво в clojure - PullRequest
2 голосов
/ 13 апреля 2011

Я начал изучать clojure, но у меня возникли проблемы с обдумыванием определенных понятий.Например, я хочу взять эту функцию и преобразовать ее так, чтобы она вызывающе вызывала get-origlabels.

(defn get-all-origlabels []
    (set (flatten (map get-origlabels (range *song-count*)))))

Моя первая попытка использовала рекурсию, но взорвала стек ( song-счет составляет около 10000).Я не мог понять, как это сделать с помощью хвостовой рекурсии.

get-origlabels возвращает набор при каждом вызове, но значения часто повторяются между вызовами.На самом деле функция get-origlabels читает файл (отдельный файл для каждого значения от 0 до song-count -1) и возвращает слова, хранящиеся в нем в наборе.

Любые указатели будут с благодарностью!

Спасибо!-Philip

Ответы [ 3 ]

7 голосов
/ 13 апреля 2011

Вы можете получить то, что хотите, используя mapcat.Я полагаю, что включение его в реальный набор Clojure приведет к его деазилизации, о чем свидетельствует тот факт, что (take 10 (set (iterate inc 0))) пытается реализовать весь набор до получения 10.

(distinct (mapcat get-origlabels (range *song-count*)))

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

(->> (iterate inc 0)
     (mapcat vector)
     (distinct)
     (take 10))

В результате вы получите последовательность, а не набор, но так как это звучит так, как будто вы действительно хотите лень здесьдумаю, что это к лучшему.

1 голос
/ 13 апреля 2011

Я бы, наверное, использовал что-то вроде:

(into #{} (mapcat get-origlabels (range *song-count*)))

В общем случае «в» очень полезно при построении структур данных Clojure. У меня есть этот мысленный образ конвейерной ленты (последовательность), сбрасывающей кучу случайных объектов в большое ведро (целевая коллекция).

1 голос
/ 13 апреля 2011

Это может иметь лучшее поведение стека

(defn get-all-origlabels []
    (reduce (fn (s x) (union s (get-origlabels x))) ${} (range *song-count*)))
...