将二进制函数传递给 Scheme 函数

Passing in a binary function into a Scheme function

如果这是一个常见问题,我们深表歉意。搜索“Racket passing in lambda as an argument”并没有 return 太多。我正在尝试编写一个 Racket 函数 lsf,它接受一个可选的 lambda 函数,并将其应用于两个相同大小列表中的相应元素。此 lambda 默认为加法。

例如,> (lsf '(2 4 5) '(6 7 8) (lambda (a b) (- b a))) 应该 return 一个列表 '(4 3 3)

> (lsf '(2 5) '(3 6)) returns '(5 11)(默认为加法)。

这是我目前的情况:

( define ( lsf list1 list2 )
    ( if ( null? list1 )
        '()
        ( cons( + ( car list1 list2 )) 
            ( lsf ( cdr list1 ) ( cdr list2 )))
    )
)

如何将此默认加法函数添加为参数(我认为它在 list2 之后?),以及如何使用它代替 cons 之后的“+”?

在参数列表中使用.定义一个rest-arg,它得到所有附加参数的列表。如果提供了可选参数,这将是 non-null 并且您可以将参数作为其第一个元素。

(define (lsf list1 list2 . rest)
  (if (null? list1)
      '()
      (let ((func (if (null? rest) + (first rest)))) ; default func to +
        (cons (func (car list1) (car list2))
              (lsf (cdr list1) (cdr list2) func)))))

如果使用的是#lang racket你可以使用by position optional parameters:

(define (lsf list1 list2 [combine +])
  (if (null? list1)
      '()
      (cons (combine (car list1) (car list2))
            (lsf (cdr list1) (cdr list2) combine))))

除了rest-argsoptionals(见其他答案),Racket还有case-lambda(如 r6rs 方案),所以:

#lang racket

(define lsf
  (case-lambda
    [(list1 list2) ;; (Listof Number) (Listof Number) -> (Listof Number)
     ;; produce list of sums of corresponding elements of list1, list2
     (lsf list1 list2 +) ]
    [(list1 list2 combine) ;; (Listof X) (Listof Y) (X Y -> Z) -> (Listof Z)
     ;; produce list applying combine to corresponding elements
     (if (null? list1)
         '()
         (cons (combine (car list1) (car list2)) 
               (lsf (cdr list1) (cdr list2) combine))) ]))

然后:

> (lsf '(2 5) '(3 6))
'(5 11)

> (lsf '(1 2 3) '(#\a #\b #\c) make-string)
'("a" "bb" "ccc")