Racket 如何绕过curry评估其论点?

Racket 如何绕过curry评估其论点?,racket,currying,Racket,Currying,假设我有一个函数,我们称它为getio data,它从shell命令获取数据。现在我需要一个检查某些内容的函数:检查io数据。看来,定义它的等效方法最终会有所不同。使用“传统”定义,我得到一个函数,该函数根据计算时(获取io数据)的结果给出结果。但是,如果我使用curry,我将得到一个函数,该函数取决于定义时(获取io数据)的结果。为了减少混淆,这里有一个例子: 使用传统定义: (define (check-io-data x) (equal? (get-io-data) x)) ... (ch

假设我有一个函数,我们称它为
getio data
,它从shell命令获取数据。现在我需要一个检查某些内容的函数:
检查io数据
。看来,定义它的等效方法最终会有所不同。使用“传统”定义,我得到一个函数,该函数根据计算时
(获取io数据)
的结果给出结果。但是,如果我使用
curry
,我将得到一个函数,该函数取决于定义时
(获取io数据)
的结果。为了减少混淆,这里有一个例子:

使用传统定义:

(define (check-io-data x) (equal? (get-io-data) x))
...
(check-io-data 0) ;; Now (get-io-data) is being evaluated
使用咖喱:

(define check-io-data (curry equal? (get-io-data))) ;; Now (get-io-data) is being evaluated
...
(check-io-data 0)
我想我知道为什么它们是不同的,因为在第一种情况下,整个函数体可能以一种特殊的方式进行计算,因为它是一个函数体,在第二种情况下,我定义了一些东西是函数的结果;这个函数在定义时被求值,以得到实际的定义,并求值函数,它必须求值参数

有没有办法做到这一点的自由或只是不工作?从理论上讲,这两个定义不应该完全相同吗?

简单回答 语法应该是

(define (check-io-data data) 
  ((curry equal?) (get-io-data) data))
讨论 由于
检查io数据
是一个参数的函数,因此必须将其定义为一个参数。因为
equal?
是一个arity=2的函数,所以在curry时必须传递两个参数

在示意图形式中,这是:

> (define f (lambda (x) (equal? 'curried-argument x)))
> (f 'curried-argument)
#t
> (f 1)
#f
相当于:

> (define (f x) ((curry equal?) 'curried-argument x))
> (f 'curried-argument)
#t
> (f 1)
#f
示例 结论 当前函数必须
将自身定义为函数[即
(定义(名称参数…(主体))
],以建立
当前创建的
lambda
的算术

#lang racket

;;; Use a generator to simulate
;;; a non-idempotent procedure
(require racket/generator)
(define get-io-data
  (infinite-generator
   (yield 1)
   (yield 2)
   (yield 3)))

(define (check-io-data x)
  ((curry equal?) (get-io-data) x))

(check-io-data 1)  ; #t
(check-io-data 1)  ; #f
(check-io-data 1)  ; #f
(check-io-data 1)  ; #t