我正在學習Scheme中的宏系統,我認爲實現curried函數將是一個好的開始。這是我製作的:使用宏的Scheme中的Currying函數
(define-syntax function
(syntax-rules()
((_() body ...) (lambda() body ...))
((_ (param) body ...) (lambda (param) body ...))
((_ (param_1 param_2 params ...) body ...) (lambda (param_1 . rest)
(let ((k (function (param_2 params ...) body ...)))
(if (null? rest) k (apply k rest)))))
((_ name params body ...) (define name (function params body ...)))))
此代碼按預期工作。舉例如下我可以定義一個add
功能:
(function add (x y) (+ x y))
然後我可以正常調用它:
(add 2 3) ; => 5
此外,我可以很容易地部分地應用它:
(map (add 10) '(2 3 5 7)) ; => (12 13 15 17)
現在我正在考慮允許具有其他參數的函數被粘貼。所以我增加了一個新的語法規則:
((_ (param . params) body ...) (lambda (param . params) body ...))
不幸的是,當我嘗試使用這個法則它給了我一個錯誤創建一個函數:
(function add (x . y) (apply + `(,x ,@y)))
這是錯誤消息:
Error: invalid syntax in macro form: (x . y)
Call history:
<eval> (##sys#= len7 0)
<eval> (loop11 (##sys#cdr l6) (##sys#+ len7 -1))
<eval> (##sys#cdr l6)
<eval> (##sys#+ len7 -1)
<eval> (##sys#= len7 0)
<eval> (loop11 (##sys#cdr l6) (##sys#+ len7 -1))
<eval> (##sys#cdr l6)
<eval> (##sys#+ len7 -1)
<eval> (##sys#= len7 0)
<eval> (##sys#eq? l6 (quote()))
<eval> (##sys#car tail15)
<eval> (##sys#cdr tail15)
<eval> (##sys#cons (rename14 (##core#syntax lambda)) (##sys#cons param body))
<eval> (rename14 (##core#syntax lambda))
<eval> (##sys#cons param body)
<syntax> (##core#lambda add (x . y) (apply + (quasiquote ((unquote x) (unquote-splicing y))))) <-
我做錯了什麼?
這是**不**創建_curried_函數;它正在創建_partially applied_函數。用'(define(fxyz)(+ x(* yz)))(define g(curry f 1))','((g 2)3)'應該返回7.但是你必須調用'((curry g 2)3)。而在OP代碼之後,'(函數g(xyz)(+ x(* yz)))','(g 1 2 3)'=='((g 1 2)3)'=='(( (g 1)2)3)'== 7。 –