果果编程课】006 超级魔法组合 —— 把魔法连成一条龙!

课程目标(45分钟)
学会使用 condfilterfoldrapplycompose 这五个超级魔法,让程序变得更聪明、更简洁、更强大!

核心口诀
小魔法一个一个用很累,把它们串起来,就能变出超级大魔法!

今天的故事背景
果果开了一家“魔法糖果店”!
客人买糖果有不同优惠规则,还要算总价、挑贵的糖果、给价格加税……
我们要用新学的魔法,一口气把这些事情都变得超级简单!

第一部分:问题引入(5分钟)

老师开场:

“上节课我们学会了 ifmap,果果已经能给每个价格加标签了!
但是现在客人买很多糖果,要做这些事:

  1. 根据数量决定打几折(10个以上9折、5-9个95折……)
  2. 从一堆糖果里挑出贵的(>50元的)
  3. 算所有糖果的总价
  4. 把价格先翻倍、再加10%税、最后变成“XX元”显示

如果还用嵌套 if 和好几个 map,代码会变得很长很乱!
今天我们学习5个超级魔法,把这些小步骤像搭积木一样连起来!”

板书示意图:

1
2
3
4
5
6
7
8
9
10
11
原材料(糖果数量、价格列表)

[cond] → 决定折扣

[filter] → 挑出贵的

[foldr] → 算总价

[compose] → 超级价格流水线(翻倍 → 加税 → 转文字)

超级结果!

第二部分:多条件选择神器 —— cond(8分钟)

基本写法

1
2
3
4
5
6
(define count 7)

(cond [(>= count 10) "9折!超级优惠🌟"]
[(>= count 5) "95折!很棒哦👍"]
[(> count 0) "原价购买~💰"]
[else "下次再来玩哦~😊"])

运行结果(count = 7):"95折!很棒哦👍"

比喻
cond 就像一个有很多岔路的选择精灵,每条路都有一个问题,只要回答“是”,就走这条路,不用一层套一层 if 了!

动手练习(学生自己改数字试试)

1
2
3
4
5
6
(define weather "cloudy")

(cond [(string=? weather "sunny") "去踢足球!⚽"]
[(string=? weather "cloudy") "去画画!🎨"]
[(string=? weather "rainy") "在家看动画!📺"]
[else "先睡觉吧~😴"])

第三部分:魔法筛子 & 魔法累加器(12分钟)

1. filter —— 魔法筛子

1
2
3
4
(define prices (list 10 60 35 120 45 80))

(filter (lambda (p) (> p 50)) prices)
; 结果:'(60 120 80)

比喻:filter 就像一个会挑东西的筛子,只留下符合条件的糖果。

练习:挑出80分以上的成绩

1
2
3
(define scores (list 95 82 68 91 75 88 60))
(filter (lambda (s) (>= s 80)) scores)
; 结果:'(95 82 91 88)

2. foldr —— 魔法累加器(从右往左累加)

1
2
3
4
5
(define prices (list 10 60 35 120))

(foldr + 0 prices) ; 225
(foldr * 1 (list 2 3 4)) ; 24
(foldr string-append "" (list "果" "果" "最" "棒")) ; "果果最棒"

比喻:foldr 就像一个从右边开始“叠加”的小工人,把所有东西按规则加/乘/拼接起来。

练习:算及格成绩的总分

1
2
3
(define scores (list 95 82 68 91 75 88 60))
(define pass-scores (filter (lambda (s) (>= s 60)) scores))
(foldr + 0 pass-scores) ; 总分

第四部分:超级组合技 —— apply & compose(15分钟)

1. apply —— 一口气喂饱魔法

1
2
3
(apply + (list 10 20 30 40))          ; 100
(apply max (list 95 82 68 91 75)) ; 95
(apply string-append (list "果果" " " "超" "棒")) ; "果果 超棒"

比喻:apply 就像把一篮子东西直接倒进魔法锅里,不用一个一个喂。

2. compose —— 终极魔法流水线(最重要!)

完整可运行代码(注意要加 require)

1
2
3
4
5
6
7
8
9
10
11
#lang racket

(define add-tax (lambda (p) (+ p (* p 0.1)))) ; 加10%税
(define double (lambda (p) (* p 2))) ; 翻倍
(define to-yuan (lambda (p) (string-append (number->string p) "元")))

(define super-price
(compose to-yuan add-tax double)) ; 从右往左:先翻倍 → 加税 → 转文字

(map super-price (list 10 50 100))
; 结果:'("22元" "110元" "220元")

计算过程(以 50 为例): 1. double → 100 2. add-tax → 100 + 10 = 110 3. to-yuan → "110元"

超级练习:自己设计一条流水线

1
2
3
4
5
6
7
8
9
; 目标:先×3 → 再+20 → 最后加“分”变成字符串
(define ×3 (lambda (n) (* n 3)))
(define add20 (lambda (n) (+ n 20)))
(define to-fen (lambda (n) (string-append (number->string n) "分")))

(define super-score (compose to-fen add20 ×3))

(map super-score (list 10 20 30))
; 应该得到:'("50分" "80分" "110分")

第五部分:综合创作时间(5分钟)

终极挑战:果果的超级糖果店计算器

请小朋友组合使用今天学的魔法,完成以下功能(老师可以给提示):

输入:糖果价格列表 + 购买数量
输出: - 先用 cond 判断能打几折 - 用 filter 挑出 >50 元的贵糖果 - 用 foldr 算总价(可先打折) - 用 compose 做最终价格显示(翻倍模拟“会员价” → 加税 → 加“元”)

鼓励孩子们自由发挥,写出最酷的组合方式!

第六部分:总结与作业(3分钟)

今天学会的五大超级魔法

  • cond → 多条件选择,比嵌套 if 更清晰
  • filter → 魔法筛子,挑出想要的
  • foldr → 累加/拼接神器
  • apply → 一口气喂一堆参数
  • compose → 把多个魔法串成流水线(最强!)

回家作业(三选二)

  1. cond 写一个“今天心情决定器”(心情 + 天气 → 决定做什么)
  2. filter + foldr 计算 (list 45 78 92 65 88 95 72) 中 85 分以上的总分和平均分
  3. compose 设计一个“超级分数处理器”:先×2 → 再+15 → 最后加“超级分”三个字
果果编程第6课

下节课预告
“下节课我们要学习递归魔法
一个魔法可以自己召唤自己,就像俄罗斯套娃一样,无限强大!
准备好迎接最酷的循环方式了吗?✨”

果果们,今天你们已经从“单个小魔法师”升级成了“魔法工厂工程师”!
继续加油,下节课见~ 🚀

遗留问题,过滤>100元的。

1
2
3
4
5
6
7
8
9
10
11
#lang racket
(define add-tax (lambda (p) (+ p (* p 0.1)))) ; 加10%税
(define double (lambda (p) (* p 2))) ; 翻倍
(define to-yuan (lambda (p) (string-append (number->string p) "元")))

(define (super-price lst)
(for/list ([p lst]
#:when (> (add-tax (double p)) 100))
(to-yuan (add-tax (double p)))))

(super-price (list 10 50 100))