如何检查功能是否部分?

Dom*_*k G 5 clojure currying partial

是否有可能在Clojure中检查某些内容是否属于部分功能?

最好有类似的东西(partial? (partial + 10))

提前致谢

Mic*_*ent 16

不,因为partial创建的函数只是"正常"函数.但是,您可以使用一些元数据,如下所示:

(defn partial2 [f & more]
  (with-meta (apply partial f more) {:partial true}))

(def partial-plus (partial2 + 1 2))

(meta partial-plus) ;;=> {:partial true}
Run Code Online (Sandbox Code Playgroud)

虽然没有真正考虑过这种方法的后果......

Kotarak想出了一个更好的解决方案,但并非总能如此.比如说:

(partial? (partial + 1)) ;;=> true
(partial? (partial + 1 2)) ;;=> false
Run Code Online (Sandbox Code Playgroud)

这有效:

(defn partial? [f]
  (let [[fst snd] (-> (class f) (.getName) (string/split #"\$"))]
    (= ["clojure.core" "partial"] [fst snd])))
Run Code Online (Sandbox Code Playgroud)

string/split是clojure.string(1.3)或clojure.contrib.str-utils2(1.2)中的split函数.


kot*_*rak 5

你可以用黑客攻击.

user=> (let [partial-classes (map class [(partial + 1)
                                         (partial + 1 2)
                                         (partial + 1 2 3)
                                         (partial + 1 2 3 4)])]
         (defn partial?
           [x]
           (some #(instance? % x) partial-classes)))
#'user/partial?
user=> (partial? (partial - 1))
true
user=> (partial? (partial - 1 2))
true
user=> (partial? (partial - 1 2 3))
true
user=> (partial? (apply partial - 1 2 [3 4 5]))
true
Run Code Online (Sandbox Code Playgroud)

编辑:根据Michiel的评论修正.你必须知道内脏partial确认了hacky性质.