简体   繁体   English

在有条件的 Scheme (R5RS) 上应用操作

[英]Applying operations on Scheme (R5RS) with a condition

I'm trying to create a Scheme program (Language R5RS) which applies an operation to a set of lists, depending on how big a number is on a list.我正在尝试创建一个 Scheme 程序(Language R5RS),它将操作应用于一组列表,具体取决于列表上的数字有多大。

So the function looks like所以函数看起来像

(apply-function f g)

The condition is, if f(ab) where a < 5, then apply operation f(ab).条件是,如果 f(ab) 其中 a < 5,则应用操作 f(ab)。

But if a is equal or greater than 5, apply g(ab).但如果 a 等于或大于 5,则应用 g(ab)。 (The second operation) (第二次操作)

This sounds confusing but a visual example should clear it up: So, an example would be这听起来令人困惑,但一个直观的例子应该会澄清它:所以,一个例子是

((apply-function '* '+) '((2 3) (8 6)))

Would return:会返回:

'(6 14)

Another example would be另一个例子是

((apply-function '* '+) '((5 7) (2 3) (3 3))

Returns退货

'(12 6 9)

I've tackled operations on Scheme before, but the condition part is throwing me off and I'm not sure where to start.我以前处理过 Scheme 上的操作,但条件部分让我失望,我不知道从哪里开始。 Any help is appreciated!任何帮助表示赞赏!

Version 1 : If you use procedures + and * instead of symbols '+ and '* :版本 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))))

Version 2 : You can make an association list matching symbols to procedures版本 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))))

Version 3 : Uses eval版本 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))))

Suppose that the procedureswere given as * and + .假设程序以*+给出。

Then the operation on one such sub-list would look like然后对一个这样的子列表的操作看起来像

(lambda (e) (if (< (car e) 5) 
                (* (car e) (cadr e))
                (+ (car e) (cadr e)))

Abstract the given procedures:抽象给定的程序:

(define (apply-once f g)
        (lambda (e)
              (if (< (car e) 5) 
                  (f (car e) (cadr e))
                  (g (car e) (cadr e)))))

Now you can transform a list with * and + :现在您可以使用*+转换列表:

(lambda (ls) (map (apply-once * +) ls))

And abstract the procedures again:并再次抽象程序:

(define (apply-function f g) 
        (lambda (ls) (map (apply-once f g) ls)))

If you assume that you don't have to map between function names & functions, then an obvious definition is to use apply :如果您假设您不必在函数名称和函数之间进行映射,那么一个明显的定义是使用apply

(define (apply-function f g)
  (lambda (l)
    (map (lambda (e)
           (apply (if (< (car e) 5) f g) e))
         l)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM