如何在方案中编写自柯里化的 lambda 宏?
How to write a self currying lambda macro in scheme?
我想写这样的函数:
(define foo (\ (a b c) (+ a (+ b c))))
让它自动转换成这样:
(define foo (lambda (a) (lambda (b) (lambda (c) (+ a (+ b c))))))
并像这样使用它(如果可能的话):
(map (foo 1 2) (interval 1 10))
好像我在写这个:
(map ((foo 1) 2) (interval 1 10))
我不知道如何在方案中编写宏,但我需要编写一个转换引用表达式的函数
(f arg1 arg2 argn)
像这样:
(define-macro clambda ;curried lambda
(lambda xs
(if (< (length xs) 2)
(if (eq? 1 (length xs))
(lambda () xs)
(lambda (head xs) (tail xs)))
(lambda (head xs) (clambda (tail xs))))))
我该怎么做?
这是我对您的宏的建议:
(define-syntax \
(syntax-rules ()
[(_ "build" (a) body)
(lambda (a . rest)
(if (null? rest)
body
(error "Too many arguments")))]
[(_ "build" (a b ...) body)
(lambda (a . rest)
(define impl (\ "build" (b ...) body))
(if (null? rest)
impl
(apply impl rest)))]
[(_ (a b ...) body)
(\ "build" (a b ...) body)]
[(_ . rest) (error "Wong use of \")]))
(define test (\ (a b c) (+ a b c)))
(define partial (test 4 5))
(partial 6) ; ==> 15
这确实会使生成的代码有更多的开销,因为每个 lambda 都会在获得更多参数时应用下一个。如果您传递太多参数,它也会产生错误,否则您会得到不清楚的“应用程序,而不是过程”
error
您可能需要实施。
我想写这样的函数:
(define foo (\ (a b c) (+ a (+ b c))))
让它自动转换成这样:
(define foo (lambda (a) (lambda (b) (lambda (c) (+ a (+ b c))))))
并像这样使用它(如果可能的话):
(map (foo 1 2) (interval 1 10))
好像我在写这个:
(map ((foo 1) 2) (interval 1 10))
我不知道如何在方案中编写宏,但我需要编写一个转换引用表达式的函数
(f arg1 arg2 argn)
像这样:
(define-macro clambda ;curried lambda
(lambda xs
(if (< (length xs) 2)
(if (eq? 1 (length xs))
(lambda () xs)
(lambda (head xs) (tail xs)))
(lambda (head xs) (clambda (tail xs))))))
我该怎么做?
这是我对您的宏的建议:
(define-syntax \
(syntax-rules ()
[(_ "build" (a) body)
(lambda (a . rest)
(if (null? rest)
body
(error "Too many arguments")))]
[(_ "build" (a b ...) body)
(lambda (a . rest)
(define impl (\ "build" (b ...) body))
(if (null? rest)
impl
(apply impl rest)))]
[(_ (a b ...) body)
(\ "build" (a b ...) body)]
[(_ . rest) (error "Wong use of \")]))
(define test (\ (a b c) (+ a b c)))
(define partial (test 4 5))
(partial 6) ; ==> 15
这确实会使生成的代码有更多的开销,因为每个 lambda 都会在获得更多参数时应用下一个。如果您传递太多参数,它也会产生错误,否则您会得到不清楚的“应用程序,而不是过程”
error
您可能需要实施。