在条件下对 Scheme (R5RS) 应用操作
Applying operations on Scheme (R5RS) with a condition
我正在尝试创建一个 Scheme 程序(语言 R5RS),它根据列表中数字的大小将操作应用于一组列表。
所以函数看起来像
(apply-function f g)
条件是,如果 f(a b) 其中 a < 5,则应用操作 f(a b)。
但如果 a 等于或大于 5,则应用 g(a b)。 (第二次操作)
这听起来令人困惑,但一个直观的例子应该可以解释清楚:所以,一个例子是
((apply-function '* '+) '((2 3) (8 6)))
会 return:
'(6 14)
另一个例子是
((apply-function '* '+) '((5 7) (2 3) (3 3))
Returns
'(12 6 9)
我以前处理过 Scheme 上的操作,但条件部分让我失望,我不确定从哪里开始。感谢您的帮助!
版本 1:如果您使用过程 +
和 *
而不是符号 '+
和 '*
:
#lang r5rs
(define apply-function
(lambda (f g)
(lambda (lop)
(map (lambda (p)
(if (< (car p) 5)
(f (car p) (cadr p))
(g (car p) (cadr p))))
lop))))
(display ((apply-function * +) '((2 3) (8 6))))
(newline)
(display ((apply-function * +) '((5 7) (2 3) (3 3))))
版本 2:你可以创建一个关联列表匹配符号到过程
#lang r5rs
(define proc-list `((* . ,*) (+ . ,+)))
(define (get-proc s)
(let ((p (assq s proc-list)))
(if p (cdr p) s)))
(define apply-function
(lambda (f g)
(lambda (lop)
(map (lambda (p)
(if (< (car p) 5)
((get-proc f) (car p) (cadr p))
((get-proc g) (car p) (cadr p))))
lop))))
(display ((apply-function '* '+) '((2 3) (8 6))))
(newline)
(display ((apply-function '* '+) '((5 7) (2 3) (3 3))))
版本 3:使用 eval
#lang r5rs
(define (my-eval e)
(eval e (scheme-report-environment 5)))
(define apply-function
(lambda (f g)
(lambda (lop)
(map (lambda (p) (if (< (car p) 5)
(my-eval (list f (car p) (cadr p)))
(my-eval (list g (car p) (cadr p)))))
lop))))
(display ((apply-function '* '+) '((2 3) (8 6))))
(newline)
(display ((apply-function '* '+) '((5 7) (2 3) (3 3))))
假设给定的过程为*
和+
。
那么对这样一个子列表的操作看起来像
(lambda (e) (if (< (car e) 5)
(* (car e) (cadr e))
(+ (car e) (cadr e)))
抽象给定的程序:
(define (apply-once f g)
(lambda (e)
(if (< (car e) 5)
(f (car e) (cadr e))
(g (car e) (cadr e)))))
现在您可以使用 *
和 +
转换列表:
(lambda (ls) (map (apply-once * +) ls))
并再次抽象程序:
(define (apply-function f g)
(lambda (ls) (map (apply-once f g) ls)))
如果您假设您不必在函数名称和函数之间进行映射,那么一个明显的定义是使用 apply
:
(define (apply-function f g)
(lambda (l)
(map (lambda (e)
(apply (if (< (car e) 5) f g) e))
l)))
我正在尝试创建一个 Scheme 程序(语言 R5RS),它根据列表中数字的大小将操作应用于一组列表。
所以函数看起来像
(apply-function f g)
条件是,如果 f(a b) 其中 a < 5,则应用操作 f(a b)。
但如果 a 等于或大于 5,则应用 g(a b)。 (第二次操作)
这听起来令人困惑,但一个直观的例子应该可以解释清楚:所以,一个例子是
((apply-function '* '+) '((2 3) (8 6)))
会 return:
'(6 14)
另一个例子是
((apply-function '* '+) '((5 7) (2 3) (3 3))
Returns
'(12 6 9)
我以前处理过 Scheme 上的操作,但条件部分让我失望,我不确定从哪里开始。感谢您的帮助!
版本 1:如果您使用过程 +
和 *
而不是符号 '+
和 '*
:
#lang r5rs
(define apply-function
(lambda (f g)
(lambda (lop)
(map (lambda (p)
(if (< (car p) 5)
(f (car p) (cadr p))
(g (car p) (cadr p))))
lop))))
(display ((apply-function * +) '((2 3) (8 6))))
(newline)
(display ((apply-function * +) '((5 7) (2 3) (3 3))))
版本 2:你可以创建一个关联列表匹配符号到过程
#lang r5rs
(define proc-list `((* . ,*) (+ . ,+)))
(define (get-proc s)
(let ((p (assq s proc-list)))
(if p (cdr p) s)))
(define apply-function
(lambda (f g)
(lambda (lop)
(map (lambda (p)
(if (< (car p) 5)
((get-proc f) (car p) (cadr p))
((get-proc g) (car p) (cadr p))))
lop))))
(display ((apply-function '* '+) '((2 3) (8 6))))
(newline)
(display ((apply-function '* '+) '((5 7) (2 3) (3 3))))
版本 3:使用 eval
#lang r5rs
(define (my-eval e)
(eval e (scheme-report-environment 5)))
(define apply-function
(lambda (f g)
(lambda (lop)
(map (lambda (p) (if (< (car p) 5)
(my-eval (list f (car p) (cadr p)))
(my-eval (list g (car p) (cadr p)))))
lop))))
(display ((apply-function '* '+) '((2 3) (8 6))))
(newline)
(display ((apply-function '* '+) '((5 7) (2 3) (3 3))))
假设给定的过程为*
和+
。
那么对这样一个子列表的操作看起来像
(lambda (e) (if (< (car e) 5)
(* (car e) (cadr e))
(+ (car e) (cadr e)))
抽象给定的程序:
(define (apply-once f g)
(lambda (e)
(if (< (car e) 5)
(f (car e) (cadr e))
(g (car e) (cadr e)))))
现在您可以使用 *
和 +
转换列表:
(lambda (ls) (map (apply-once * +) ls))
并再次抽象程序:
(define (apply-function f g)
(lambda (ls) (map (apply-once f g) ls)))
如果您假设您不必在函数名称和函数之间进行映射,那么一个明显的定义是使用 apply
:
(define (apply-function f g)
(lambda (l)
(map (lambda (e)
(apply (if (< (car e) 5) f g) e))
l)))