2009-01-18 28 views
6

Đang cố gắng để làm bài tập 1.16 (phiên bản lặp đi lặp lại của nhanh exp) trong "Cấu trúc và Giải thích chương trình máy tính" với Clojure tôi đến với điều này:Đánh giá một phần của Clojure cond

(defn fast-it-exp [base exp res] 
    (cond (= exp 0) res 
    (odd? exp) fast-it-exp base (- exp 1) (* base res) 
    :else fast-it-exp base (/ exp 2) (* base base res))) 

Đang cố gắng nó ra:

user=> (fast-it-exp 0 0 10) 
10 ;yep 
user=> (fast-it-exp 2 2 2) 
1  ;no... 
user=> (fast-it-exp 1 1 1) 
#<user$fast_it_exp__59 [email protected]> ;huh?! 

Có vẻ phần "lẻ" của biểu thức cond trả về hàm thay vì đánh giá. Tại sao? Tôi đã thử đặt dấu ngoặc đơn quanh các biểu thức sau các biến vị ngữ nhưng dường như cú pháp không chính xác, đây là cách tốt nhất mà tôi có thể đưa ra. Tôi đang sử dụng rev 1146 của Clojure.

+0

Nếu bạn muốn áp dụng một chức năng, sau đó nó có lẽ đã có một dấu mở ngoặc bên trái của chinh no. Và trong dòng cuối cùng của bạn không có '(' trước 'nhanh-nó-exp'. Và không chỉ ở dòng cuối cùng ... –

Trả lời

11

Hãy thử điều này:

(defn fast-it-exp [base exp res] 
    (cond (= exp 0) res 
     (odd? exp) (fast-it-exp base (- exp 1) (* base res)) 
     :else (fast-it-exp base (/ exp 2) (* base base res)))) 

Tôi không có REPL tiện dụng nhưng là trông giống như những gì bạn muốn.

+0

Cái quái gì, tôi nghĩ tôi đã thử tất cả hoán vị có thể có của dấu ngoặc đơn, nhưng có vẻ như tôi đã bỏ lỡ Điều đó làm việc, cảm ơn rất nhiều Philip. :) –

+0

Ahum. Tại sao hoán vị của dấu ngoặc đơn? Nếu bạn muốn gọi một hàm trong Lisp, nó phải là phần tử đầu tiên của danh sách; đây là cách cú pháp Lisp hoạt động. – Svante

+0

Trong dấu ngoặc đơn Clojure sau khi biến vị ngữ là tùy chọn, như sau ví dụ (= exp 0) ở trên. Đã thử mà không có, nhưng cú pháp đó là mơ hồ. Đã thử với, nhưng tôi có thể đã có một dấu ngoặc đơn xung quanh: khác là không chính xác. Nghĩ rằng tôi cũng đã thử phiên bản của Philip, nhưng chắc đã làm điều gì đó sai. –

6

Về cơ bản, những gì bạn đã viết có thể được định dạng như:

(defn fast-it-exp [base exp res] 
    (cond 
    (= exp 0) res 
    (odd? exp) fast-it-exp 
    base (- exp 1) 
    (* base res) :else 
    fast-it-exp base 
    (/ exp 2) (* base base res))) 

Vì vậy:

user=> (fast-it-exp 0 0 10) ; (= exp 0) => res 
10 ;yep 
user=> (fast-it-exp 2 2 2) ; base => (- exp 1) 
1  ;no... 
user=> (fast-it-exp 1 1 1) ; (odd? exp) => fast-it-exp 
#<user$fast_it_exp__59 [email protected]> ;huh?! 
+0

Ah, tôi hiểu, điều đó giải thích hành vi ban đầu, cảm ơn. Ngoài ra tôi đã quản lý để làm toán một cách chính xác ngay bây giờ, heh. * đỏ mặt * –

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