2012-02-27 44 views
5

Có khả năng kiểm tra xem một chức năng nào đó có phải là một phần trong Clojure không?Làm cách nào để kiểm tra xem chức năng có phải là một phần không?

Tốt nhất nên có một cái gì đó như (partial? (partial + 10))?

Cảm ơn trước

+2

Chỉ cần tò mò: tại sao bạn cần điều đó? – viebel

+1

@Yehonathan Tôi đang thực hiện Shen trong Clojure và ở đó tôi cần phải khác nhau giữa các chức năng bình thường và các chức năng một phần. (Do các quyết định thiết kế). –

+0

Thần là gì? Ngoài ra, những gì về chức năng ẩn danh được tạo ra thông qua '#()'? – viebel

Trả lời

16

Không, bởi vì chức năng được tạo ra một phần chỉ là chức năng "bình thường". Bạn tuy nhiên có thể sử dụng một số siêu dữ liệu cho nó, như thế này:

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

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

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

Chưa thực sự nghĩ thông qua những hậu quả của phương pháp này mặc dù ...

Kotarak đã đưa ra một giải pháp đẹp hơn mà làm việc, nhưng không phải lúc nào. Ví dụ thực hiện việc này:

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

này hoạt động:

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

với chuỗi/split là chức năng tách ra từ clojure.string (1.3) hoặc clojure.contrib.str-utils2 (1.2).

+0

clojure.string cũng bằng 1,2. –

+0

Có lẽ bạn cũng nên kiểm tra 'clojure.core', không chỉ' phần'. – kotarak

+0

Điểm tốt, cố định nó. –

2

Các chức năng được tạo ra một phần chỉ là các chức năng bình thường, nhưng nếu bạn bị bẻ cong trên đó, có thể điều gì đó như thế này có thể giúp ích? :

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

Tuyên bố từ chối trách nhiệm: Tôi không biết nếu điều gì đó như thế này là chống lừa đảo.

5

Bạn có thể bị hack.

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: Đã sửa lỗi theo nhận xét của Michiel. Rằng bạn phải biết nội tại của partial xác nhận bản chất hacky.

Các vấn đề liên quan