单个谓词来测试Clojure中的“自我评估”原子

时间:2011-06-29 12:06:35

标签: clojure predicate

Clojure的主页上,有以下声明:

  

字符串,数字,字符,true,   false,nil和keywords评估为   自己。

是否有一个组合谓词可以测试其中任何一个,结合string?number?char?true?false?,{{1 }和nil?。我应该使用keyword?吗?

3 个答案:

答案 0 :(得分:3)

也许我错过了一些东西,但您可以使用以下内容来测试任何这些条件,如果有的话,则返回true:

(defn self-eval?
  [x]
  (or (string? x)
      (number? x)
      (char? x)
      (keyword? x)
      (true? x)
      (false? x)
      (nil? x)))

答案 1 :(得分:2)

编写一个宏,询问“给定的表达式是否对自身进行评估”是很容易的。事实上,这是一个很好的例子,只能用宏来完成,因为他们需要看到评估和未评估的参数。

(defmacro selfp [a] `(= ~a (quote ~a)))
#'user/selfp
user> (selfp 1)
true
user> (selfp +)
false
user> (selfp [1 2])
true
user> (selfp '(+ 1 2 3))
false

虽然字符串,数字,字符,关键字和布尔值都是自我评估的,但[1 2]等其他内容也是如此,因此这可能不是一般有用的测试。

答案 2 :(得分:0)

另一种选择是创建一个使用地图的函数:

(defn myclassifier? [x]
   (let [types-I-care-about #{java.lang.Sring ...}]
      (if (types-I-care-about (type x))
          true
          false)))

可能具有更好性能的另一个选择是使用java的动态:

(extend-type Object
  IMyClassifier
  (myclassifier? [x]
            (let [c (.getClass x)]
             (if (types-I-care-about (type c))
               (do
                 (extend-type (.getClass x)
                   IMyClassifier
                   (myclassifier? [x] true))
                 true)
               false))))

其中type-I-care-about是您关心的一组类型。