在球拍中实现自己的排序

时间:2013-10-09 18:05:10

标签: lambda scheme racket sequencing

我需要实现一个带有一个或多个表达式的函数,并按顺序执行这些表达式。

这是我到目前为止所做的:

(define (foo exp0 exp1 ) exp0 exp1)

3 个答案:

答案 0 :(得分:1)

假设您有以下表达式

(sequence form1 form2 form3)

并且您希望按顺序评估表单,然后您不能将它们传递给Josuha解释的函数。最简单的转换是将上面的内容改为

((lambda () form1 form2 form3))

因为lambda表达式中的表单是按顺序执行的,结果是最后一个表单的值。由于此转换必须在源代码级别完成,因此您必须使用宏,例如:

(define-syntax-rule (sequence form1 form2 ...)
  ((lambda () form1 form2 ...)))

将转换表达式,例如

(sequence (display "a") (display "b") (display "c"))

((lambda () (display "a") (display "b") (display "c")))

将按顺序执行表单。

答案 1 :(得分:0)

Scheme不指定任何特定的参数评估顺序。这意味着如果您有display-and-return函数:

(define (display-and-return x)
  (display x)
  x)

然后你打电话,例如,

(list (display-and-return 1) (display-and-return 2))

您可以保证获得结果(1 2),但您可以看到显示为1221输出。但是,Scheme确实指定在计算函数体之前计算函数的参数。因此,您可以通过使它们成为函数的参数来对两个表达式进行排序:

((lambda (val1)
   ((lambda (val2)
      (list val1 val2))
    (display-and-return 2)))
 (display-and-return 1))

通常,您可以使用这样的转换将(seq exp1 exp2 ... expm expn)转换为

((lambda (val1)
   ((lambda (val2)
      ...
        ((lambda (valm)
           expn)        ; or ((lambda (valn) valn) expn)
         expm) ... )
    exp2))
 exp1)

您可以使用define-syntax-rule定义这种转换。

答案 2 :(得分:-1)

你需要一些带有“一个或多个表达式”的东西,然后对它们进行评估并返回最后一个。这可以通过以下方式定义:

(define (sequence exp1 . exps)
  (car (reverse (cons exp1 exps))))       ; (if (null? exps) exp1 ...)

然后您将其调用为:

> (sequence (+ 1 2) (* 1 2) 17)
17

不需要使用define-syntax stuff,因为标准函数应用程序将“按顺序执行那些表达式”

如果您需要从左到右保证订单,那么您需要:

(define-syntax sequence
  (syntax-rules ()
    ((sequence exp exps ...)
     (begin exp expos ...))))

但如果您无法使用begin,但可以使用lambda,那么:

(define-syntax sequence
  (syntax-rules ()
    ((sequence exp exps ...)
     ((lambda () exp exps ...)))))