Подтвердить что ты не робот

Каков правильный способ clojure, чтобы проверить, не является ли коллекция непустой

Я хочу написать функцию, которая вернет логическое значение true, если данная коллекция не пуста и false в противном случае.

Я мог бы сделать

defn ..
(boolean (seq coll))

или

defn ..
(not (empty? coll))

Поскольку я новичок в clojure, я изначально склонялся к # 2 (более читаемый), но ссылка clojure api для empty? явно говорит, что вместо (not (empty? coll)) используется idiom (seq coll), возможно, чтобы избежать двойного отрицания.

Я хочу знать, что такое clojure, чтобы проверить, не является ли коллекция непустой и возвращает логическое значение true/false.

4b9b3361

Ответ 1

Прохождение из empty? docstring, о котором вы говорили, означает, в частности, что такая функция nonempty? никогда не должна быть необходимой или даже особенно полезной, поскольку seq всегда может стоять за ней в булевых контекстах, которые в чистом виде Clojure код может быть.

Если вы хотите написать такую ​​функцию, тем не менее, я скажу, что мне нравится первый подход лучше. empty? построена на seq в любом случае, так что не избежать его вызова; просто выведение результата в Boolean кажется более чистым, чем две поездки через not. Для других вариантов см., Например, nil?, false? (я по-прежнему предпочитаю актерский состав).

Кстати, почему вы хотите написать это...? Возможно, для вызова метода Java с аргументом boolean? В этом случае, я думаю, что актер будет красиво выражать намерение.

Обновление: Пример для иллюстрации последней точки:

  • Простой класс Java:

    public class Foo {
      public static boolean foo(boolean arg) {
        return !arg;
      }
    }
    
  • Код клиента Clojure:

    (Foo/foo nil)
    ; => NullPointerException
    (Foo/foo (boolean nil))
    ; => true
    

Ответ 2

Согласно Радости Clojure, nil punning с seq является идиоматическим:

(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

"... использование seq в качестве условия завершения - это идиоматический способ проверить, является ли последовательность пустой. Если мы протестировали [в приведенном выше примере] только s вместо (seq s), тогда условие завершения не произойдет даже для пустых коллекций..."

Ответ 3

В дополнение к Michal Marczyk отличный ответ, я укажу, что существует определенная непустая функция:

http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-empty

но он не делает именно то, о чем вы просите. (Хотя он будет работать в большинстве ситуаций).

Непустая возвращает nil, если коллекция пуста, и сама коллекция, если коллекция не пуста. Для предикатных тестов это будет работать хорошо. Если вам действительно нужны истинные и ложные значения, то (not (empty? X)) это то, что вам нужно.