假设我有一些功能,让我们称之为get-io-data
,例如从shell命令获取数据。现在我想要一个检查某些东西的函数:check-io-data
。似乎应该是等同于定义它的方式最终会有所不同。使用传统的'定义我得到一个函数,根据评估时(get-io-data)
的结果给出结果。但是,如果我使用curry
,我将得到一个函数,该函数取决于定义时(get-io-data)
的结果。为了让它更容易混淆,这是一个例子:
使用传统定义:
(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-time进行评估,以获取实际定义并评估其评估参数的函数。
有没有办法做到这一点,或者只是不会工作?从理论上讲,这两个定义不应该完全相同吗?
答案 0 :(得分:1)
语法是,
(define (check-io-data data)
((curry equal?) (get-io-data) data))
因为check-io-data
是一个参数的函数,所以它必须这样定义。因为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
#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
一个curried函数必须define
本身作为一个函数[即(define (name arg...)(body))
]以确定由lambda
创建的curry
的arity。