【问题标题】:Question about foldl function in Racket. (Functional programming)关于 Racket 中的 foldl 功能的问题。 (函数式编程)
【发布时间】:2020-05-16 13:34:42
【问题描述】:
所以我有这行代码:
(foldl cons '() '(1 2 3 4))
我运行它时得到的输出是这样的:
'(4 3 2 1)
你能解释一下为什么我没有得到'(1 2 3 4)吗?
我阅读了文档,但我仍然对 foldl 的工作原理有些困惑。另外,如果我想定义foldl,我将如何在 Racket 中指定该函数可以将可变数量的列表作为参数?
谢谢!
【问题讨论】:
标签:
functional-programming
scheme
racket
variadic-functions
fold
【解决方案1】:
是的。根据左折叠的定义,使用列表的第一个元素和到目前为止的累积结果调用组合函数,并传递该调用的结果(如到目前为止新的、更新的累积结果)到具有相同组合函数和列表其余部分的 foldl 的递归调用:
(foldl cons '() '(1 2 3))
=
(foldl cons (cons 1 '()) '(2 3))
=
(foldl cons (cons 2 (cons 1 '())) '(3))
=
(foldl cons (cons 3 (cons 2 (cons 1 '()))) '())
=
(cons 3 (cons 2 (cons 1 '())))
并且当列表为空时,将到目前为止累积的结果作为最终结果返回。
对于第二个问题,Scheme 中的可变参数函数在参数列表中用点 . 指定,如下所示:
(define (fold-left f acc . lists)
(if (null? (first lists)) ;; assume all have same length
acc
(apply fold-left ;; recursive call
f
(apply f (append (map first lists) ;; combine first elts
(list acc))) ;; with result so far
(map rest lists)))) ;; the rests of lists
确实,
(fold-left (lambda (a b result)
(* result (- a b)))
1
'(1 2 3)
'(4 5 6))
返回-27。