2012-02-27 11 views
5

Clojureで何かが一部の機能であるかどうかを確認することはできますか?機能が部分的かどうかを確認するにはどうすればよいですか?

(partial? (partial + 10))のようなものがありますか?事前

+2

好奇心が強い:なぜそれは必要ですか? – viebel

+1

@Yehonathan私はClojureでShenを実装しています。そこでは、通常の関数と部分関数の間で異なる必要があります。 (設計上の決定による)。 –

+0

シェンとは何ですか?また、 '#()'で作成された無名関数はどうでしょうか? – viebel

答えて

16

おかげいいえ、部分によって作成された機能は、単に「通常」の機能であるため。 ただし、このように、それのためにいくつかのメタデータを使用することができます。

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

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

(meta partial-plus) ;;=> {:partial true} 

は本当にこのアプローチの結果を通じて考えていないけれども...

Kotarakが働くよりよい解決策を考え出したが、常にではない。たとえば、これを取る:

(partial? (partial + 1)) ;;=> true 
(partial? (partial + 1 2)) ;;=> false 

これは動作します:

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

を文字列/分割は、分割関数であると(1.3)またはclojure.contrib.str-utils2(1.2)clojure.stringから。

+0

clojure.stringも1.2です。 –

+0

'partial'だけでなく、' clojure.core'もテストするべきでしょう。 – kotarak

+0

良い点、それを修正しました。 –

2

partialで作成された関数は普通の関数ですが、もしあなたが地獄に陥っているのであれば、おそらくこのようなものが役に立ちますか? :

(defn partial? 
    [f] 
    (clojure.contrib.string/substring? "partial" (str (class f)))) 

免責事項:このようなものがばかばかしいかどうかわかりません。

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 

EDIT:ミシェルさんのコメントに応じて修正しました。あなたがpartialの内臓を知る必要があることは、ハッキーな性質を確認します。

関連する問題