(define-struct pizza (size toppings))
;; Constants for testing
(define (meat item)
(symbol=? 'meat item))
(define (tomatoes item)
(symbol=? 'tomatoes item))
(define (cheese item)
(symbol=? 'cheese item))
(define (pepperoni item)
(symbol=? 'pepperoni item))
(define (hot-peppers item)
(symbol=? 'hot-peppers item))
(define (count-toppings order topping)
(cond [(empty? order) 0]
[else
(local
[(define (single-pizza-tops pizza top)
(length (filter top (pizza-toppings pizza))))
(define (list-of-nums lop tops)
(list (single-pizza-tops (first lop) tops)
(single-pizza-tops (first (rest lop)) tops)
(single-pizza-tops (first (rest (rest lop))) tops)))]
(foldr + 0 (list-of-nums order topping)))]))
原来我的代码在定义的常量下运行良好,但是count-toppings不会使用'topping'的符号?
有没有人知道修改我的过滤器功能的方法,这样如果我为浇头输入一个符号,这个代码的工作方式是否相同?
答案 0 :(得分:0)
Map
和filter
可以foldr
和cons
来实施。由于您没有构建列表,因此可以忽略filter
和map
。通常,虽然将递归映射到高阶函数,但您可以查看类型签名。更难的方法是手动将代码与函数匹配。
Map获取列表,函数或arity,并返回映射到列表中每个元素的函数列表或Haskell notaion中的(a -> b) -> [a] -> [b]
。
(define (map f L) ;niave implementation pared down for simplicity
(if (null? L)
'()
(cons (f (car L)) (map f (cdr L)))))
Filter获取arity的谓词和列表,并返回一个满足谓词的列表。或者在Haskell中(a -> bool) -> [a] -> [a]
。
(define (filter pred L) ;dirro
(cond ((null? L) '())
((pred (car L))
(cons (car L)
(filter pred (cdr L))))
(else (filter pred (cdr L)))))
Foldr接受一个具有arity 2,累加器值和列表的函数,并返回累加器。或者(a -> b -> b) -> b -> [a] -> b
在哈斯克尔。
(define (foldr kons knil L) ;ditto
(if (null? L)
knil
(kons (car L) (foldr kons knil (cdr L)))))
首先,它的诀窍是从你的函数中缓和适合的论点。在你的两个函数中你都有一个cond子句[(empty? topping-list) 0]
,这表明knil应该是0
。
在count-topping
的else语句中你调用+,乍一看建议kons应该是+,但是你的列表不是直接数字,这意味着你必须用lambda语句包装,或者创建辅助功能。 (lambda (x acc) (+ (single-pizza-toppings (pizza-toppings x) atop) acc))
把它放在一起
(define (count-topping alop atop)
(foldr (lambda (x acc)
(+ (single-pizza-toppings (pizza-toppings x) atop)
acc))
0
alop))
现在有趣的一个,single-pizza-toppings
看起来非常相似。执行lambda
语句将包含if
语句,如果x是等于topping的符号,则返回1,否则返回0。或者你可以做一些更简单的事情。
(define (single-pizza-toppings topping-list topping)
(foldr (lambda (x acc)
(+ 1 acc))
0
(filter (lammba (x) (symbol=? x topping))
topping-list)))
过滤器过滤器确保每个x
前往foldr
都是顶部,因此您可以忽略它并添加到累加器。
答案 1 :(得分:0)
假设我们有第一个,我们可以通过
定义第二个map
即,
(define (count-toppings pizzas topping)
(sum (map (lambda (p) (single-pizza-toppings (pizza-toppings p) topping)) pizzas)))
对于第一个函数,我们可以使用filter
来获取给定顶部的所有出现的列表。
出现次数是结果的长度:
(define (single-pizza-toppings toppings topping)
(length (filter (lambda (t) (symbol=? t topping)) toppings)))
这两个函数都包含将输入转换为我们感兴趣的数据map
和filter
,然后是“缩减”,sum
和{{1} }。
这是一种非常常见的模式。
如果你没有length
:
sum
答案 2 :(得分:-2)
看起来你的第一步就是整理一套完整的测试用例。如果您正在使用DrRacket,则可能需要在“选择语言...”菜单中启用“语法测试套件覆盖率”以确保您拥有一组良好的测试。那是第一步......