2016-10-11 2 views
2
généralisant

Supposons que j'ai la fonction suivante:carte des valeurs de Racket

(define foo 
    (lambda (n) 
    (values n (* 2 n)))) 

Je veux appeler carte foo sur la liste '(1 2 3 4). Par conséquent, je crée une fonction 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)))] 
    ))) 

Maintenant, je peux faire ce qui suit:

(map-values foo '(1 2 3 4)) => (values '(1 2 3 4) '(2 4 6 8)) 

Cependant, si foo renvoie trois valeurs, ou quatre, etc ...? Je vais devoir créer une nouvelle fonction map-values pour chaque cas. Y at-il un moyen de généraliser map-values de sorte que peut travailler avec n'importe quel foo qui renvoie plusieurs valeurs?

Répondre

3

Cela fait ce que vous voulez:

(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) 

Ceci est compatible avec les systèmes standards ainsi.