【问题标题】:How does the following reduce?以下如何减少?
【发布时间】:2021-06-18 22:21:49
【问题描述】:

我有以下过程来添加三个数字:

(define add-3 (lambda (x y z) (+ x y z)))
(add-3 100 200 300)
; 600

将其转换为柯里化函数时,它会简化为以下内容,

(apply (lambda args1
         (apply add-3 (cons 100 args1)))
       '(200 300))
; 600

我的问题是上述如何进一步减少?例如,如果我在列表中替换 args1=(200 300) 我会得到以下信息:

(apply (lambda args1
         (apply add-3 (cons 100 args1)))
       '(200 300))

(apply
 (apply add-3 (cons 100 '(200 300))))

但这给了我arity mismatch,所以我在减少/替换中一定做错了什么。这样做的正确方法是什么?

我想一个更直接的方式来问这个问题是如何进行以下简化?

(apply (lambda args (apply add-3 args)) '(100 200 300))
; 600

; ... how do we get here?
(apply add-3 '(100 200 300))
; 600

对于上下文:https://stackoverflow.com/a/68038585/651174

【问题讨论】:

  • 减少与链接答案中的完全相同 - 从(apply (lambda args1 (apply add-3 ...))(apply add-3 (cons 100 '(200 300)))。您似乎从 (apply fn ls) 转到 (apply (fn ls)),但这是不正确的。
  • @molbdnilo 谢谢,我在这里的回答有意义吗?我花了一些时间浏览它...stackoverflow.com/a/68075322/651174

标签: scheme lisp racket apply currying


【解决方案1】:

以此为基准重新开始:

(define add-3 (lambda (x y z) (+ x y z)))
(add-3 100 200 300)
; 600

然后我们从我们想要减少的函数开始:

(apply (lambda args1
         (apply add-3 (cons 100 args1)))
       '(200 300))

我们如何减少这种情况?申请工作如下:

(apply + '(1 2))
(      +   1 2 )
3

也就是说,它需要一个过程并将其应用于提供的列表中的参数。因此,首先,我们可以采用“内部 lambda 函数”并应用它:

((lambda args1 (apply add-3 (cons 100 args1))) 200 300)

这不是很简单,但我们可以设置args1='(200 300) 来去掉那个组件,这给了我们:

(let ((args1 '(200 300)))
  (apply add-3 (cons 100 args1)))

我们可以在这里走几条路线,但为了简化,让我们调用(cons 100 args1),它简化为(100 200 300)

(let ((args1 '(200 300)))
  (apply add-3 '(100 200 300)))

请注意,我们的正文中不再包含 args1,因此我们可以删除 let

(apply add-3 '(100 200 300))

现在我们可以使用 (apply func args) 的 apply 定义 -> (func arg1 arg2 ...) 得到:

(add-3 100 200 300)

这正是我们想要的。请注意,在我们的缩减中,我们能够利用以下优势:

(apply (lambda args BODY) LIST)

并将其转化为:

(let ((args LIST))
    BODY)

这里最简单的例子是这样的:

(apply (lambda args (length args)) '(1 2 3 4))
;  {
;    BODY = (length args)
;    LIST = '(1 2 3 4)
;  }
;  ==>
(let ((args '(1 2 3 4)))
    (length args))

有关更多信息,此答案提供了其他上下文:https://stackoverflow.com/a/68048663/651174

【讨论】:

  • 好,是的。唯一的事情是,我会将FUNC 重命名为BODY。因为它不是函数,它是函数的主体。
【解决方案2】:

您是在问如何解构列表?

(define l1 (list 100 200 300))
(apply (lambda args (apply add-3 args)) l1)

(define l2 (cons 100 (cons 200 (cons 300 '()))))
(apply (lambda args (apply add-3 args)) l2)

https://en.wikibooks.org/wiki/Scheme_Programming/List_Operations

【讨论】:

    猜你喜欢
    • 2015-05-12
    • 2021-09-14
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 2013-04-15
    相关资源
    最近更新 更多