Clojure печать ленивой последовательности

Я пытаюсь распечатать свое двоичное дерево, но Clojure дает мне трудное время распечатывать последовательности должным образом.

Итак, у меня есть список узлов '(1 2 3), например.

В каждой итерации я хочу распечатать node с рядом пробелов до и после каждого элемента.

(defn spaces [n]
  (apply str (repeat n " ")))

Отлично, это похоже на работу.

Итак, предположим, что у меня есть список nodes '(:a :b :c), который я хочу распечатать в одной строке, с указанными пробелами.

(println (map #(str (spaces before) % (spaces (dec before))) nodes))

У меня есть список элементов. Используя карту, я получаю список строковых объектов. Отлично, поэтому я могу их распечатать!

Но это дает мне следующее:

([email protected] [email protected] [email protected])

Итак, я искал, как печатать ленивые последовательности, и я пришел к использованию команды print-str. Согласно документам, это печатает строку, которая затем возвращается.

(println (print-str (map #(str (spaces before) % (spaces (dec before))) nodes)))

Но это дает мне следующее:

([email protected] [email protected] [email protected])

Без изменений.. Герм. Любая помощь приветствуется.

Ответ 1

user> (str (map inc (range 10)))
"[email protected]"
user> (pr-str (map inc (range 10)))
"(1 2 3 4 5 6 7 8 9 10)"

Метод toString LazySeq вызывается str, и это позволяет избежать ленивой последовательности значений путем непрозрачного отображения идентификатора объекта. Функция pr-str вызывает мультиметод print-dup объекта, который предназначен для получения версии вещи, которая может быть понята читателем (поэтому для LazySeq буквальное значение, которое сделает равным LazySeq).

Для правильного форматирования структур просмотрите пространство имен clojure.pprint, которое поставляется с clojure.core, которое имеет pprint, print-table и различные функции для настройки поведения красивой печати. ​​

user> (require '[clojure.pprint :as pprint :refer [pprint print-table]])
nil
user> (pprint [:a [:b :c :d [:e :f :g] :h :i :j :k] :l :m :n :o :p :q [:r :s :t :u :v] [:w [:x :y :z]]])
[:a
 [:b :c :d [:e :f :g] :h :i :j :k]
 :l
 :m
 :n
 :o
 :p
 :q
 [:r :s :t :u :v]
 [:w [:x :y :z]]]
nil
user> (print-table (map #(let [start (rand-int 1e6)] (zipmap % (range start (+ start 10)))) (repeat 5 [:a :b :c :d :e :f :g :h :i :j])))

|     :a |     :c |     :b |     :f |     :g |     :d |     :e |     :j |     :i |     :h |
|--------+--------+--------+--------+--------+--------+--------+--------+--------+--------|
| 311650 | 311652 | 311651 | 311655 | 311656 | 311653 | 311654 | 311659 | 311658 | 311657 |
|  67627 |  67629 |  67628 |  67632 |  67633 |  67630 |  67631 |  67636 |  67635 |  67634 |
| 601726 | 601728 | 601727 | 601731 | 601732 | 601729 | 601730 | 601735 | 601734 | 601733 |
| 384887 | 384889 | 384888 | 384892 | 384893 | 384890 | 384891 | 384896 | 384895 | 384894 |
| 353946 | 353948 | 353947 | 353951 | 353952 | 353949 | 353950 | 353955 | 353954 | 353953 |
nil