Переменные аргументы для проектной функции Римана

Итак, я работаю над потоковой функцией, которая будет суммировать некоторые показатели для нескольких событий. Для этого я использую функцию project, и она выглядит примерно так:

(project [(func (:service event) (nth service-list 0))      
          (func (:service event) (nth service-list 1))
          (func (:service event) (nth service-list 2))]
         (..))

service-list — это аргумент функции окружения, который содержит вектор сервисов, которые необходимо сложить. func — это функция, которая принимает два аргумента и возвращает true/false Использование приведенного выше фрагмента работает нормально, но я хотел бы иметь возможность упростить его, чтобы работал вектор, который больше или меньше 3 элементов.

Пока у меня это:

    (project (mapv (fn[service] (
                   `func (:service event) ~service)
                   ) service-list)))
             (..)

который, я думаю, возвращает вектор функций, которые не оценены. Я пошел с этим подходом, как только понял, что project — это макрос. Не знаю, правильно ли я поступаю...


person Zara Kay    schedule 28.09.2017    source источник


Ответы (1)


Проблема, с которой вы столкнулись, заключается в том, что вы не можете динамически собирать только аргументы вызова макроса. Поэтому вам нужно динамически собрать весь вызов макроса.

Вы можете создать форму clojure и вызвать для нее eval. Возьмите следующее.

    (let [args (mapv #(list 'func (:service 'event) %) service-list)
          form (list 'project args (...))]
      (eval form))

Или вы также можете использовать riemann.streams/project*. function для использования функций-предикатов вместо выражений where.

person erdos    schedule 28.09.2017