2011-12-21 31 views
25

Tôi đã sử dụng erlang trong quá khứ và nó có một số thứ thực sự hữu ích như chức năng khớp mẫu hoặc "bảo vệ chức năng". Ví dụ từ tài liệu erlang là:Chức năng khớp mẫu trong Clojure?

fact(N) when N>0 -> 
    N * fact(N-1); 
fact(0) ->  
    1.  

Nhưng điều này có thể được mở rộng đến một ví dụ phức tạp hơn nhiều nơi dưới dạng tham số và giá trị bên trong nó được kết hợp.

Có điều gì tương tự trong clojure không?

+0

Đây là một câu hỏi cũ nhưng điều này dự án mở rộng core.match cho các chức năng và gần như chính xác những gì tôi đã hỏi năm trước https://github.com/killme2008/defun – mikkom

Trả lời

27

Có công việc liên tục để thực hiện việc này với sự hợp nhất trong thư viện core.match (https://github.com/clojure/core.match).

Tùy thuộc vào chính xác những gì bạn muốn làm, một cách phổ biến khác là sử dụng defmulti/defmethod để gửi các chức năng tùy ý. Xem http://clojuredocs.org/clojure_core/clojure.core/defmulti (ở cuối trang đó là ví dụ giai thừa)

+3

core.match gần như chính xác những gì tôi đang tìm kiếm ở cấp mã, là phần này của cốt lõi của 1.3 (tôi không hiểu chính xác cách c công việc đóng gói lojure)? Với một số macro, tôi nghĩ rằng có thể mở rộng cú pháp thành hàm (IMHO trong erlang mã rõ ràng nhất có thể được viết với chức năng khớp mẫu với bảo vệ) – mikkom

+0

Yêu cầu 1.3 nhưng không phải là một phần của 1.3 theo mặc định. Nếu bạn đang sử dụng Leiningen (https://github.com/technomancy/leiningen) - và bạn nên - sau đó bạn thêm một dòng '[org.clojure/core.match "0.2.0-alpha8"]' vào phụ thuộc project.clj của bạn, sau đó chạy lein deps. Và có như bạn có thể thấy ở dưới cùng của trang github của họ, các devs kế hoạch để áp dụng core.match cho các chức năng (predicate dispatch) sớm. – gilesc

+0

Nếu bất kỳ ai khác gặp phải các mẫu đối số chức năng đối sánh sự cố, hãy sử dụng 'vec': http://nickknowlson.com/blog/2013/02/17/using-core-match-with-function-arguments/ –

9

core.match là thư viện phù hợp với mẫu có thể mở rộng và đầy đủ tính năng cho Clojure. Với một chút ma thuật vĩ mô và bạn có thể có được một xấp xỉ gần đúng với những gì bạn đang tìm kiếm.

3

Ngoài ra, nếu bạn muốn tách riêng các cấu trúc đơn giản như vectơ và bản đồ (bất kỳ thứ gì là chuỗi hoặc bản đồ, ví dụ như bản ghi, trên thực tế) cũng có thể sử dụng destructuring bind. Đây là dạng kết hợp mẫu yếu hơn, nhưng vẫn rất hữu ích. Mặc dù nó được mô tả trong phần let ở đó, nó có thể được sử dụng trong nhiều ngữ cảnh, bao gồm các định nghĩa chức năng.

+2

Phá hủy cấu trúc là một bit quá giới hạn cho khớp mẫu thực. – mikkom

12

Tôi muốn giới thiệu defun, đó là một macro để xác định hàm có khớp mẫu giống như erlang, dựa trên core.match. Chức năng thực tế trên có thể được viết thành:

(use 'defun) 
(defun fact 
    ([0] 1) 
    ([(n :guard #(> % 0))] 
    (* n (fact (dec n))))) 

Một ví dụ khác, một ắc từ zero đến số dương n:

(defun accum 
    ([0 ret] ret) 
    ([n ret] (recur (dec n) (+ n ret))) 
    ([n] (recur n 0))) 

Xem thêm thông tin xin vui lòng xem https://github.com/killme2008/defun

+1

Thật đẹp! Chúc may mắn với dự án Tôi chắc chắn nó sẽ giúp rất nhiều người như các chức năng phù hợp với mô hình là một trong những điều bị đánh giá thấp nhất trong lập trình. – mikkom

+0

@ killme2008, tôi thực sự thích công việc của bạn với defun. Những lợi thế của defun trên core.match là gì? –

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