Recursion 使用常量而非符号的筛选器代码

Recursion 使用常量而非符号的筛选器代码,recursion,filter,scheme,racket,Recursion,Filter,Scheme,Racket,事实证明,我的代码可以很好地处理定义的常量,但count toppings不能处理“topping”的符号 有人知道如何修改我的过滤函数,以便在我输入浇头符号时,该代码也能以同样的方式工作吗?看起来您的第一步将是组合一套完整的测试用例。如果您使用的是DrRacket,您可能希望在“选择语言…”菜单中启用“语法测试套件覆盖率”,以确保您有一组好的测试。这是第一步….Map和filter可以按照foldr和cons实现。由于您没有构建列表,因此可以忽略过滤器和映射。一般来说,要将递归映射到高阶函数,

事实证明,我的代码可以很好地处理定义的常量,但count toppings不能处理“topping”的符号


有人知道如何修改我的过滤函数,以便在我输入浇头符号时,该代码也能以同样的方式工作吗?

看起来您的第一步将是组合一套完整的测试用例。如果您使用的是DrRacket,您可能希望在“选择语言…”菜单中启用“语法测试套件覆盖率”,以确保您有一组好的测试。这是第一步….

Map
filter
可以按照
foldr
cons
实现。由于您没有构建列表,因此可以忽略
过滤器
映射
。一般来说,要将递归映射到高阶函数,可以查看类型签名。更困难的方法是手动将代码与函数的代码进行匹配

Map获取一个列表、一个函数或一个arity,并返回映射到列表中每个元素的函数列表或Haskell标记中的
(a->b)->[a]->[b]

(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)))]))
筛选器接受一个arityone谓词和一个列表,并返回一个用于验证该谓词的列表。或者在Haskell中的
(a->bool)->[a]->[a]

(define (map f L) ;niave implementation pared down for simplicity 
 (if (null? L)
     '()
     (cons (f (car L)) (map f (cdr L)))))
Foldr接受一个a函数,该函数具有算术2、累加器值和列表,并返回累加器。或者在haskell中的
(a->b->b)->b->[a]->b

(define (filter pred L) ;dirro
 (cond ((null? L) '())
       ((pred (car L))
        (cons (car L)
              (filter pred (cdr L))))
       (else (filter pred (cdr L)))))
因此,它的诀窍首先是缓和函数中的参数,使其适合。在这两个函数中,您都有一个cond子句
[(空?顶部列表)0]
,这表明knil应该是
0

count topping
的else语句中,您调用+,乍一看,这表明kon应该是一个+,但是您的列表不是直接的数字,这意味着您必须在lambda语句中换行,或者创建一个helper函数<代码>(lambda(x acc)(+(单个比萨配料(比萨配料x)顶部)acc))

拼凑

(define (foldr kons knil L) ;ditto
  (if (null? L) 
      knil
      (kons (car L) (foldr kons knil (cdr L)))))
有趣的是,
单一比萨配料
看起来非常相似。执行
lambda
语句将包含
if
station,如果x是等于topping的符号,则返回1,否则返回0。或者你可以做一些更简单的事情

(define (count-topping alop atop)
  (foldr (lambda (x acc) 
            (+ (single-pizza-toppings (pizza-toppings x) atop)       
               acc))  
         0
         alop))

该过滤器确保每个进入
foldr
x
都是顶部,因此您可以忽略它并添加到累加器中

假设我们有第一个,我们可以通过

  • 通过
    map
  • 计算结果列表的和
  • 就是

    (define (single-pizza-toppings topping-list topping)
      (foldr (lambda (x acc)
               (+ 1 acc))
             0
             (filter (lammba (x) (symbol=? x topping))
                     topping-list)))
    
    对于第一个函数,我们可以使用
    filter
    获取给定浇头的所有出现的列表。
    出现次数是结果的长度:

    (define (count-toppings pizzas topping)
      (sum (map (lambda (p) (single-pizza-toppings (pizza-toppings p) topping)) pizzas)))
    
    这两个函数都包括将输入转换为我们感兴趣的数据,
    map
    filter
    ,然后是“reduce”、
    sum
    length

    这是一种非常常见的模式

    如果您没有
    总和

    (define (single-pizza-toppings toppings topping)
      (length (filter (lambda (t) (symbol=? t topping)) toppings)))
    

    测试用例?例如check expects?虽然这是一个好的实践,但它并不能解决手头的问题,即如何根据高阶函数进行推理。
    (define (sum ts)
      (foldr (lambda (x acc) (+ x acc)) 0 ts))