【问题标题】:curry in scheme咖喱计划
【发布时间】:2020-05-08 10:51:44
【问题描述】:

我有这个curry 函数:

(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))

我觉得就像(define curry (f a b))

我的任务是用curry写一个函数consElem2All,它应该像这样工作

(((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 转换它。谁能帮帮我?

提前致谢

熊熊

【问题讨论】:

    标签: scheme currying


    【解决方案1】:

    您应该从阅读有关柯里化的内容开始。如果你不明白 curry 是什么意思,可能真的很难使用它……在你的情况下,http://www.engr.uconn.edu/~jeffm/Papers/curry.html 可能是一个好的开始。

    currying 的一个非常常见且有趣的用法是使用 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))
    

    然后是 curried 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)
    

    希望能帮助你掌握柯里化的用处...

    【讨论】:

    • 吹毛求疵:您的 add 定义缺少右括号,并且您的 (creduce + 0) 调用应该是 ((creduce +) 0),因为 creduce 需要一个参数。
    • 我通常禁止自己发布我没有从成功运行的代码中复制/粘贴的代码。不错的收获!
    • @Nowhereman 嗨,您的答案中给出的链接似乎已关闭。您能否指出另一种学习柯里化的资源?
    • @dannny 在 WayBack Machine 中仍然可以访问,不过:web.archive.org/web/20140330131408/http://www.engr.uconn.edu/…
    【解决方案2】:

    所以你的 curry 版本需要一个带有两个 args 的函数,比如说:

    (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 curry 成cons 从而得到一个可以直接用于映射的单参数函数?...

    【讨论】:

      【解决方案3】:
      (define (consElem2All0 x lst) 
        (map ((curry cons) x) lst))
      

      【讨论】:

        猜你喜欢
        • 2014-02-19
        • 1970-01-01
        • 2018-02-02
        • 2018-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多