在 Racket 中概括地图值

Aad*_*hah 4 scheme functor racket multiple-return-values

假设我有以下函数:

(define foo
  (lambda (n)
    (values n (* 2 n))))
Run Code Online (Sandbox Code Playgroud)

我想foo通过列表调用 map '(1 2 3 4)。因此,我创建了一个map-values函数:

(define map-values
  (lambda (f xs)
    (match xs
      ['() (values '() '())]
      [(cons x xs)
        (let-values ([(a  b)  (f x)]
                     [(as bs) (map-values f xs)])
          (values (cons a as) (cons b bs)))]
      )))
Run Code Online (Sandbox Code Playgroud)

现在,我可以执行以下操作:

(map-values foo '(1 2 3 4)) => (values '(1 2 3 4) '(2 4 6 8))
Run Code Online (Sandbox Code Playgroud)

但是,如果foo返回三个值或四个值……等等怎么办?我需要map-values为每种情况创建一个新函数。有没有一种方法可以泛化,map-values以便可以与foo返回多个值的任何方法一起使用?

Syl*_*ter 5

这就是你想要的:

(define (map-values proc lst)
  (define (wrap e)
    (call-with-values (lambda () (proc e)) list))      
  (apply values
         (apply map list (map wrap lst))))

(define (foo n)
  (values n (* 2 n) (/ 1 n)))

(map-values foo '(1 2 3 4))
; ==> (1 2 3 4)
; ==> (2 4 6 8)
; ==> (1 1/2 1/3 1/4)
Run Code Online (Sandbox Code Playgroud)

这也与标准方案兼容。