Должен ли я реализовать интерфейс Seq в clojure
У меня есть структура данных в Clojure, которая представляет собой набор результатов эксперимента:
(defprotocol ResultSet
(columns [rs] "return a collection of the columns in the resultset, represented by keywords")
(rows [rs] [rs column-keys] "returns a seq of the rows in the resultset, order and column specified as keywords by column-keys. with a single argument returns rows with all columns present"))
И у меня есть deftype
который реализует этот протокол. Я заинтересован в написании функций, которые делают такие вещи, как отображение функции на все результаты в наборе результатов, или которые сворачивают в набор результатов, делая в основном те же вещи, что и встроенные функции seq.
В Haskell я бы сделал это, реализовав соответствующие классы типов (например, Functor), а затем используя такие функции, как fmap или mfilter. Поэтому я решил заняться этим в Clojure и получил некоторые идеи по реализации интерфейса ISeq.
Так это хорошая идея? Я не могу найти много ресурсов о реализации ISeq, и мне интересно, каков идиоматический подход к этому.
2 ответа
Насколько я могу судить, "лучший" способ реализовать что-то подобное - это не реализовать ISeq, а clojure.lang.Seqable; другими словами, предоставьте реализацию (.seq) для отображения вашего ResultSet в (возможно, ленивую) последовательность. То есть маршрут, который использует clojure для большинства (всех?) Коллекций, кроме списка (списки реализуют ISeq, поскольку API seq уже является подмножеством API списков).
Я думаю, что я неправильно понимаю ваш вопрос, но разве вы не использовали бы карту, чтобы применить функцию к каждому элементу в вашем результате.