2012-02-11 41 views
73

Tôi đang học Clojure và tôi đang cố xác định hàm có số lượng tham số thay đổi (hàm variadic) và tổng hợp chúng (yep, giống như thủ tục +). Tuy nhiên, tôi không biết làm thế nào để thực hiện chức năng nàyLàm thế nào để thực hiện một hàm Clojure có một số tham số biến?

Tất cả những gì tôi có thể làm là:

(defn sum [n1, n2] (+ n1 n2))

Tất nhiên chức năng này phải mất hai parameteres và hai tham số duy nhất. Hãy dạy tôi cách làm cho nó chấp nhận (và xử lý) một số thông số không xác định.

Trả lời

93

Nói chung trường hợp, không giao hoán, bạn có thể sử dụng apply:

(defn sum [& args] (apply + args)) 

Kể từ khi bổ sung là giao hoán, một cái gì đó như thế này nên làm việc quá:

(defn sum [& args] (reduce + args)) 

& gây args được ràng buộc với phần còn lại của danh sách đối số (trong trường hợp này là toàn bộ danh sách, vì không có gì ở bên trái của &).

Rõ ràng việc xác định số tiền như vậy không có ý nghĩa, vì thay vì:

(sum a b c d e ...) 

bạn chỉ có thể viết:

(+ a b c d e ....) 
+3

Có, không tạo hàng rào, nhưng đó là minh hoạ tốt cho câu trả lời của bạn. Cảm ơn. – rodrigoalves

+0

@soulcheck: có cách nào để chuyển 'seq' vào hàm tổng của bạn không. Ví dụ: (tổng hợp '(1 2 3)) và kết quả là 6? – avichalp

+0

@avichalp sẽ là một chức năng khác. chỉ cần xóa '&' khỏi một trong hai phiên bản – soulcheck

10

defn là một vĩ mô mà làm cho việc xác định chức năng một chút đơn giản hơn. Clojure hỗ trợ quá tải arity trong một đối tượng chức năng duy nhất, tự tham khảo, và chức năng biến-arity sử dụng &

Từ http://clojure.org/functional_programming

26

Yehoanathan đề cập arity quá tải nhưng không cung cấp một ví dụ trực tiếp. Đây là những gì anh ấy nói về:

(defn special-sum 
    ([] (+ 10 10)) 
    ([x] (+ 10 x)) 
    ([x y] (+ x y))) 

(special-sum) =>20

(special-sum 50) =>60

(special-sum 50 25) =>75

15
(defn my-sum 
    ([] 0)       ; no parameter 
    ([x] x)       ; one parameter 
    ([x y] (+ x y))     ; two parameters 
    ([x y & more]     ; more than two parameters 


    (reduce + (my-sum x y) more)) 
) 
3
(defn sum [& args] 
    (print "sum of" args ":" (apply + args))) 

này có bất kỳ num ber của đối số và thêm chúng lên.

+0

Bản sao của @soulcheck câu trả lời http://stackoverflow.com/a/9242671/1327651 – nha

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