递归处理列表参数的 Racket 宏
Racket macro that recursively processes a list argument
我正在尝试编写一个宏,递归地 'unwraps' 将列表的值转换为单个值。例如,unwrap '(1 2 3))
将产生(单独):
(car '(1 2 3)) ; 1
(car (cdr '(1 2 3)) ; 2
(car (cdr (cdr '(1 2 3)) ; 3
这将像 (+ (unwrap '(1 2 3)))
==> (+ 1 2 3)
一样使用。 (我知道你可以使用标准库申请这个,但我正在尝试编写我自己的版本)。
我的问题是在编写宏时,我不知道如何递归处理传递给 unwrap 宏的列表参数。这是我尝试过的:
(define-syntax (unwrap stx)
(syntax-case stx ()
[(_ lst)
#`(begin (car lst) ; error at the last step since (car '()) is invalid
(unwrap (cdr lst)))]))
或
(define-syntax (unwrap stx)
(syntax-case stx ()
[(_ lst)
#`(if (null? lst)
'()
(car (unwrap (cdr lst))))])) ; infinite loops
这些显然都是错误的,但基本上我不知道写一个宏来检查输入列表的值(或匹配空列表模式)和 returns 在这两种情况下都有不同的东西。也有可能我完全错误地处理了这个问题,因此我们将不胜感激任何帮助。谢谢!
你想要
(+ (unwrap '(1 2 3))) ==> (+ 1 2 3)
但这是不可能的。您要求 unwrap
宏扩展为三个断开连接的形式,这是不允许的。任何宏都必须展开为一种形式。因此,正如您在问题中所说,对于您给出的示例,apply
是正确答案。
对于其他可能的用法,答案是备份一个步骤并问为什么你认为这个unwrap
功能会有用:你希望在什么情况下使用它?然后设计一个不同的解决方案,在语言的约束下工作。
我正在尝试编写一个宏,递归地 'unwraps' 将列表的值转换为单个值。例如,unwrap '(1 2 3))
将产生(单独):
(car '(1 2 3)) ; 1
(car (cdr '(1 2 3)) ; 2
(car (cdr (cdr '(1 2 3)) ; 3
这将像 (+ (unwrap '(1 2 3)))
==> (+ 1 2 3)
一样使用。 (我知道你可以使用标准库申请这个,但我正在尝试编写我自己的版本)。
我的问题是在编写宏时,我不知道如何递归处理传递给 unwrap 宏的列表参数。这是我尝试过的:
(define-syntax (unwrap stx)
(syntax-case stx ()
[(_ lst)
#`(begin (car lst) ; error at the last step since (car '()) is invalid
(unwrap (cdr lst)))]))
或
(define-syntax (unwrap stx)
(syntax-case stx ()
[(_ lst)
#`(if (null? lst)
'()
(car (unwrap (cdr lst))))])) ; infinite loops
这些显然都是错误的,但基本上我不知道写一个宏来检查输入列表的值(或匹配空列表模式)和 returns 在这两种情况下都有不同的东西。也有可能我完全错误地处理了这个问题,因此我们将不胜感激任何帮助。谢谢!
你想要
(+ (unwrap '(1 2 3))) ==> (+ 1 2 3)
但这是不可能的。您要求 unwrap
宏扩展为三个断开连接的形式,这是不允许的。任何宏都必须展开为一种形式。因此,正如您在问题中所说,对于您给出的示例,apply
是正确答案。
对于其他可能的用法,答案是备份一个步骤并问为什么你认为这个unwrap
功能会有用:你希望在什么情况下使用它?然后设计一个不同的解决方案,在语言的约束下工作。