Jeffrey Meunier有一个隐含的Curry宏here,它使用了defmacro。我想知道是否有人用语法规则写过这个?
答案 0 :(得分:3)
Scheme中有许多curry实现 - 没有一个可以像Haskell一样优雅,因为函数总是一元函数,所以一切都可以通过curry。 (但这当然可以在一个足够强大的方案中实施,如Racket。)
至于你挖出的宏 - 它是一个非常糟糕的宏:它不仅使用不卫生的宏,它还明确地调用eval
,并依赖于环境的实现等。但使用简单的syntax-rules
宏很容易做到这一点。 AFAICT,这是它实现的:
(define-syntax-rule (clambda (x ... . r) b ...)
(let ([len (length '(x ...))] [real (lambda (x ... . r) b ...)])
(let loop ([argss '()] [n 0])
(lambda args
(let ([n (+ n (length args))] [argss (cons args argss)])
(if (>= n len)
(apply real (apply append (reverse argss)))
(loop argss n)))))))
但这里有一个重要的注意事项。您引用的页面表示函数版本的问题在于它是显式的 - 但它也有一个重要的优点:使用宏实现您必须使用clambda
定义函数,而函数版本可以使用具有任何内置功能。在许多Scheme实现中,有一些工具可以检查函数的arity,使用它可以实现一个知道何时调用原始函数的currying函数版本。