Scheme能否将values结果或列表拼接为函数调用参数?
Scheme中展开多值/列表为函数调用参数的方法
标准Scheme本身不支持直接在函数调用的参数列表中间展开values的多值返回或列表为多个参数,但可以通过以下方式实现你想要的效果:
1. 手动嵌套call-with-values
这是最直接的方式,通过call-with-values捕获每个values的返回值,再传递给目标函数:
(call-with-values (lambda () (values 1 2)) (lambda (a b) (call-with-values (lambda () (values 3 4)) (lambda (c d) (list 0 a b c d 5)))))
这种方式逻辑清晰,但如果需要展开的多值表达式较多,嵌套会变得繁琐。
2. 封装辅助宏简化操作
可以自己定义一个宏,自动处理参数列表中的values表达式,将其展开为多个参数:
(define-syntax expand-values (syntax-rules (values) [(_ proc) (proc)] [(_ proc (values expr ...) rest ...) (call-with-values (lambda () (values expr ...)) (lambda args (apply expand-values (cons proc args) rest ...)))] [(_ proc arg rest ...) (expand-values (lambda args (proc arg . args)) rest ...)]))
使用这个宏时,直接把目标函数和参数列表传入即可:
(expand-values list 0 (values 1 2) (values 3 4) 5) ; 输出结果:(0 1 2 3 4 5)
3. 处理列表的情况
如果要展开的是列表而非values返回值,可以先用apply values把列表转成多值,再用上面的宏处理:
(expand-values list 0 (apply values '(1 2)) (apply values '(3 4)) 5) ; 同样输出:(0 1 2 3 4 5)
需要注意的是,标准Scheme没有内置语法支持这种“中间参数展开”,因为函数调用的参数默认是逐个求值为单一值的,多值必须通过call-with-values显式捕获。借助宏可以把这种重复逻辑封装起来,用起来更方便。
内容的提问来源于stack exchange,提问作者user11589013
相关产品推荐
相关产品推荐

