文章
Get Programming with Haskell-7
在函数式语言中编写实用代码的首要挑战之一在于:由于缺乏状态变化,传统依赖状态变更的循环结构(如 for、while 和 until 循环)将不可用。所有迭代问题都必须通过递归解决。
部分内容超过 Notion API 单页读取上限,已尽力加载可访问内容。
# 递归和模式匹配
## 1、递归
通常而言,若某事物通过自身定义自身,即构成递归。这一概念常令人望而生畏——程序员往往将其与无限循环的解包噩梦相联系。然而递归本无需如此痛苦,在编程实践中,它甚至比其他迭代形式更为自然。
以**列表(递归数据结构)**为例:列表的定义即为空列表,或一个元素后接另一列表。操作列表时无需烧脑的思维体操,其递归本质天然自洽。同理,**递归函数**就是在自身定义中调用自身的函数。初听之下确显晦涩。
但若将递归函数视为**递归过程的定义工具**,其本质便极为寻常。人类活动几乎皆为递归过程!以洗碗为例:
1. **终止条件**:水池无碗 → 洗碗完成
2. **递归步骤**:取碗 → 清洗 → 放置沥水架 → 重复直至终止条件满足
## 2、递归的规则
递归的难点在于你需要自己编写递归过程。即使是像处理列表或洗碗这种算法,从头写出来似乎也比理解它们要困难得多。编写递归函数的秘诀就是——不要去想“递归”本身!过度思考递归只会让你头疼。解决递归函数的正确方式是遵循一套简单的规则:
1. 明确最终目标。
2. 确定当达到目标时应该发生什么。
3. 列出所有可能的替代情况。
4. 确定你的“重复执行”过程(类似“冲洗再重复”)。
5. 确保每一种替代情况都能推动你朝目标前进。