Scheme - 如何汇总列表?

时间:2013-03-10 10:41:18

标签: scheme

我有一份城市名单,我希望得到最少的居民。这是一个清单:

((London United-Kingdom 100000)
 (Paris France 40000)
 (Sydney Australia 350000)
 (New-York USA 1200000))

我的代码是:

(define (aggregate proc n lst)
  (cond ((null? lst) 0)
        ((proc (n (car lst)) (aggregate proc n (cdr lst))))
        (else (aggregate proc n (cdr lst)))))

(aggregate max habitants cities) --> 1200000
(aggregate min habitants cities) --> 0 (should be 40000)

最小值应为40000. 0中的问题为((null? lst) 0),但我不知道如何重写代码。你有什么主意吗?感谢。

1 个答案:

答案 0 :(得分:2)

当然,0和40000的最小值为0.请注意,您在aggregate内使用0作为默认值。将其更改为100亿(然后您的(aggregate max ...)将无效);或者更改aggregate函数以接受另一个参数,即默认值。

像这样:

(define (aggregate proc n lst def)
  (cond ((null? (cdr lst)) def)
        ((proc (n (car lst)) (aggregate proc n (cdr lst))))
        (else (aggregate proc n (cdr lst)))))

或许不是。请注意,您正在“减少”列表中的二进制函数。只有列表不为空才有意义。所以这里根本不需要默认值 - 使用any实际上是错误的。相反,当列表中只剩下一个元素时停止:

(define (aggregate proc n lst)
  (cond ((null? (cdr lst)) (n (car lst)))
        ((proc (n (car lst)) (aggregate proc n (cdr lst))))
        (else (aggregate proc n (cdr lst)))))

选择一个或另一个。请注意,组合函数proc生成的内容必须也接受作为其第二个参数。所以在第二个变体(又名foldr1)中,它必须接受两个相同类型(类型)的参数,并且还产生相同类型的结果,即proc是{{1}类型的函数}}。但总的来说,类型(a -> a -> a)可能不同,在这种情况下,只有第一个变体(a.k.a。(a -> b -> b))才有效。