我有这个
curry
功能:
(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))
我认为这就像
(define curry (f a b))
。
我的作业是使用
consElem2All
编写一个函数 curry
,其工作原理应该像
(((consElem2All cons) 'b) '((1) (2 3) (4)))
>((b 1) (b 2 3) (b 4))
我已经按照常规方式编写了这个函数:
(define (consElem2All0 x lst)
(map (lambda (elem) (cons x elem)) lst))
但还是不知道如何用
curry
来改造它。有人可以帮助我吗?
提前致谢
熊克
您应该首先阅读有关柯里化的内容。如果你不明白咖喱是什么,可能真的很难使用它......就你而言,http://www.engr.uconn.edu/~jeffm/Papers/curry.html可能是一个好的开始。
柯里化的一个非常常见和有趣的用途是使用像reduce或map这样的函数(对于它们自己或它们的参数)。
(define curry2 (lambda (f) (lambda (arg1) (lambda (arg2) (f arg1 arg2)))))
(define curry3 (lambda (f) (lambda (arg1) (lambda (arg2) (lambda (arg3) (f arg1 arg2 arg3))))))
然后是一些柯里化的数学函数:
(define mult (curry2 *))
(define double (mult 2))
(define add (curry2 +))
(define increment (add 1))
(define decrement (add -1))
然后是柯里化的reduce/map:
(define creduce (curry3 reduce))
(define cmap (curry2 map))
首先减少用例:
(define sum ((creduce +) 0))
(sum '(1 2 3 4)) ; => 10
(define product (creduce * 1))
(product '(1 2 3 4)) ; => 24
然后映射用例:
(define doubles (cmap double))
(doubles '(1 2 3 4)) ; => (2 4 6 8)
(define bump (cmap increment))
(bump '(1 2 3 4)) ; => (2 3 4 5)
我希望能帮助您掌握柯里化的用处...
所以你的 curry 版本采用带有两个参数的函数,比方说:
(define (cons a b) ...)
并将其变成可以这样称呼的东西:
(define my-cons (curry cons))
((my-cons 'a) '(b c)) ; => (cons 'a '(b c)) => '(a b c)
您实际上有一个需要三个参数的函数。如果您有一个管理 3 元函数的
curry3
,您可以执行以下操作:
(define (consElem2All0 the-conser x lst) ...)
(就像你所做的那样,但允许使用除 cons 之外的类似 cons 的函数!)
然后这样做:
(define consElem2All (curry3 consElem2All0))
你手头没有这样的
curry3
。因此,您可以构建一个,或者通过自己“手动”柯里化额外变量来解决它。解决它看起来像:
(define (consElem2All0 the-conser)
(lambda (x lst) ...something using the-conser...))
(define (consElem2All the-conser)
(curry (consElem2All0 the-conser)))
请注意,map 表达式本身还有另一种可能的 curry 用途,即通过将 lambda 包裹在 cons 周围以将元素传递给 cons 来暗示。如何将
x
柯里化为 cons
以便获得可直接用于映射的单参数函数?...
也许最好使用通用版本:
(define (my-curry f)
(lambda args
(cond ((= (length args) 1)
(lambda lst (apply f (cons (car args) lst))))
((>= (length args) 2)
(apply f (cons (car args) (cdr args)))))))
我的任务是使用 curry 编写一个函数 consElem2All...
如果您从字面上理解这部分(忘记原始句子的第二部分),则意味着您应该在实现的主体中使用柯里化函数。
...应该像...
一样工作
我认为你自己添加了第二部分,这增加了你的困惑。
很多时候,人们所说的柯里化实际上是偏函数应用。因此,在下面的解决方案中,我没有调用
curry
curry
,而是调用 partial
。
(define (partial f . args)
(lambda more-args
(apply f (append args more-args))))
(define (cons-elem-to-all elem lst)
(map (partial cons elem) lst))
我很确定,这就是你的老师正在寻找的东西。
> (cons-elem-to-all 'b '((1) (2 3) (4)))
((b 1) (b 2 3) (b 4))
(define (consElem2All0 x lst)
(map ((curry cons) x) lst))