晚间!
我需要在Scheme中编写 reduce 函数,该函数与Python中的内置 reduce 函数一样。在Scheme中编写reduce函数很容易:
(define (reduce fn lis identity)
(if (null? lis)
identity
(fn (car lis)
(reduce fn (cdr lis) identity))))
但是,此代码与Python reduce 不同,后者仅使用两个参数(函数和要减少的项列表)。
任何人都可以帮助我编写一个以这种方式工作的Scheme函数吗?
(>(reduce *'(2 4 5 5))=> 200,是我们教授的例子。)
非常感谢,伙计和女孩们。你很有帮助< 3
ETA:对Levien先生和Jester-Young先生,非常感谢你。您提供了大量的信息,以帮助我自己解决问题。 *拥抱
答案 0 :(得分:5)
这很容易。使用列表的第一个元素初始化累加器:
(define (py-reduce f ls) (fold f (car ls) (cdr ls)))
(py-reduce * '(2 4 5 5)) => 200
随意使用另一种减少功能而不是从srfi-1折叠(如减少,折叠......)或使用自己的减少功能。你的清单至少需要一个元素。
答案 1 :(得分:2)
拥有一个标识允许你的函数使用大小为零或更多的列表 - 当它是一个空列表时,你就获得了标识。如果没有标识,该函数将仅使用一个或多个元素的列表。一些函数自然具有一个同一性(零用于加法,一个用于乘法等)。其他人则不会 - 尤其是min
和max
,特别是大in。
你应该能够弄清楚其余部分:)
答案 2 :(得分:0)
下面是一个尾递归版本。你的教授不太喜欢它(因为它没有演示递归;-)),但至少它会让你知道如何去做。
(define (reduce func lst)
(let loop ((val (car lst))
(lst (cdr lst)))
(if (null? lst) val
(loop (func val (car lst)) (cdr lst)))))
正如Raph Levien的优秀答案所示,如果传入列表为空(这就是identity
参数的用途),此版本将无效。在这种情况下,您将收到错误(因为您不能car
或cdr
为空列表。