Hanfei Sun
Hanfei Sun

Reputation: 47101

Is there a shorter way to write a function applied to a list in scheme like this?

I'm using R5RS (in racket). Here is my example

(map (lambda (x) (list (apply + x) (apply * x))) '((1 2 3) (4 5 6)))
 -> ((6 6) (15 120))

I was just wondering that if there's a built-in function like this

(map-apply '(+ *) '((1 2 3) (4 5 6)))

which could produce the same result.

Upvotes: 1

Views: 98

Answers (3)

GoZoner
GoZoner

Reputation: 70245

Are you still there +firegun? If you really, really need to pass the function arguments as '(+ *) then your solution would be:

(define (map-apply function-names items)
  (let ((funcs (map (lambda (name) (eval name (interaction-environment))) function-names)))
    (map (lambda (item)
           (map (lambda (func)
                  (apply func item))
                funcs))
         items)))

Upvotes: 0

Sylwester
Sylwester

Reputation: 48775

If you are doing these kinds of things often you can abstract the production of the map-function. Thus the rest will be unchanged:

;; Makes a function that applies all functions to an argument
(define (make-map-fun . funs)
  (lambda (lis)
     (map (lambda (fun) (apply fun lis)) funs)))

(map (make-map-fun + *) '((1 2 3) (4 5 6)))
; ==> ((6 6) (15 120))

;; And you can zip with it too
(apply map 
       (lambda l ((make-map-fun + *) l)) 
       '((1 2 3) (4 5 6) (7 8 9))) 
; ==> ((12 28) (15 80) (18 162))

Upvotes: 0

C. K. Young
C. K. Young

Reputation: 223193

Nothing built-in, but you can write your own:

(define (map-apply funcs items)
  (map (lambda (item)
         (map (lambda (func)
                (apply func item))
              funcs))
       items))

You'd have to pass in (list + *), not '(+ *), however.

Upvotes: 6

Related Questions