微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

转换为柯里化函数

如何解决转换为柯里化函数

让我们采用以下 filter 函数

#lang sicp

(define (filter function sequence)
  (if (null? sequence)
      nil
      (let ((elem (car sequence)) (rest (cdr sequence)))
        (if (function elem)
            (cons elem (filter function rest))
            (filter function rest)))))

(filter (lambda (x) (> x 3)) '(1 2 3 4 5))

以下是将其转换为柯里化函数的正确方法吗?

(define filter2
  (lambda (function)
    (lambda (sequence)
      (if (null? sequence)
          nil
          (let ((elem (car sequence)) (rest (cdr sequence)))
            (if (function elem)
              (cons elem ((filter2 function) rest))
              ((filter2 function) rest)))))))

也就是说,两者的区别在于:

  • 定义:将其定义为 (define func arg1 arg2 ...) 而不是将其称为 (define func (lambda (arg1) (lambda (arg2) (... )))
  • 调用:不是将其称为 (func arg1 arg2 ...),而是变成了 (((func arg1) arg2) ...)

是否有任何其他差异,或者更像是在执行两者时语法糖/括号中的差异?

解决方法

是的,您的双 lambda 方法确实有效。但也有更好的方法来做到这一点。

事实证明 define 可以直接执行此操作。以下两段代码完全相同:

(define f
  (lambda (x)
    (lambda (y)
      (+ x y)))

(define ((f x) y)
  (+ x y))

将此应用到上面的示例中,我们得到:

(define ((filter function) sequence)
  (if (null? sequence)
      nil
      (let ((elem (car sequence)) (rest (cdr sequence)))
        (if (function elem)
            (cons elem (filter function rest))
            (filter function rest)))))

((filter (lambda (x) (> x 3))) '(1 2 3 4 5))

此外,如果您希望将现有函数转换为柯里化变体,racket/function 模块提供了 curry

(require racket/function)

(define (f a b)
   (+ 1 2))

(((curry f) 1) 2)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。