Идиоматическое замыкание, условно вызывающее функцию - PullRequest
4 голосов
/ 04 февраля 2012

У меня есть функция clojure, которая должна выдвигать информацию на карту, если определенное условие выполняется, используя эту карту в качестве параметра для другой функции.

У меня есть следующее, но я чувствую себя неуклюже с повторными вызовами функции бара.

(defn foo ([opts]

  (if (= true (something))       
    (bar (into opts {:a b}))
    (bar opts)))

(def bar [opts])

Таким образом, если (что-то) имеет значение true, мы добавляем дополнительные параметры в параметр opts перед вызовом функции bar, в противном случае мы просто пропускаем его.

Ответы [ 4 ]

7 голосов
/ 04 февраля 2012

Во-первых, (= true (something)) можно просто заменить на (something) без проблем (если только вы на самом деле не пытаетесь различить возвращаемое значение true и возвращаемое значение, скажем, 1). Если параметры для возвращаемого значения true и false, (something) само по себе будет работать нормально. Вы также можете использовать слияние вместо в, что может быть немного яснее.

Вы можете попробовать

(bar (if (something)
       (merge opts {:a b})
       opts))

Это также сработает, хотя и включает в себя необязательный вызов merge, когда (something) ложно, хотя с nil для второго аргумента, merge должен возвращаться очень быстро.

(bar (merge opts
            (when (something)
              {:a b})))
2 голосов
/ 05 февраля 2012

Ответ Ретифа в порядке.Следует отметить, что if является выражением в Clojure, а не просто условной конструкцией.Следовательно, оно имеет возвращаемое значение, и вы можете использовать возвращаемое значение в качестве параметра для функций:

(bar (if (something)       
        (into opts {:a b})
         opts))

Вы можете думать о нем как о троичном операторе в Java.

0 голосов
/ 13 июня 2017

Обратите внимание, что начиная с Clojure 1.5 это можно записать

(cond-> opts (something) (merge {:a b}))
0 голосов
/ 04 февраля 2012

Преобразуйте условный код в функцию (и).Что-то вроде:

(defn addAIfSomethig [opt] (if (something) (into opts {:a "A"}) opt) )
(defn addBIfSomethig [opt] (if (something) (into opts {:b "B"}) opt) )

Тогда в вашей функции, где вам нужно изменить опцию перед вызовом панели, используйте композицию функций.

(defn foo [opt]
    (let [modifiers (comp addAIfSomethig addBIfSomethig)]
      (bar (modifiers opt))
    ))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...