Haskell自定义City类型下lookup触发非穷尽模式错误排查
非穷尽模式报错的根本原因
你写的getCityPopulation的函数分支,完全没有覆盖长度≥2的列表入参场景,这是触发Non-exhaustive patterns in function getCityPopulation的核心:
- 第一个函数子句的模式
getCityPopulation [] nameIn yearIn,仅能匹配入参为空列表的情况 - 第二个函数子句的模式
getCityPopulation [cs] nameIn yearIn,只会匹配长度恰好为1的列表——你准备用来测试的testData长度就是3,这类多元素输入根本匹配不到任何已定义的分支,运行时自然抛出非穷尽匹配错误。
容易踩的列表模式认知误区
你大概率是对Haskell的列表匹配规则存在理解偏差,才写出了覆盖不全的模式:
[cs]是语法糖,等价于cs : [],只会匹配长度刚好为1的列表,和“任意非空列表”没有关系- 如果要匹配所有非空列表(不管长度是1、2还是上百个元素),对应的模式写法是
cs : rest,这才能覆盖全部非空输入的场景 - 你原本的设计目标是把全量城市列表传入函数,做名称匹配查找,这类场景下入参列表的长度本来就不是固定为1的,硬把列表模式限定为单元素,自然会漏掉绝大多数实际会用到的输入分支。
现有实现和设计目标的错位
除了模式覆盖不全的报错,当前代码还有和设计初衷不匹配的逻辑问题:
- 你把空值校验(空列表、空城市名、无效年份)的逻辑和单元素列表的模式绑在了一起,这些校验属于通用入参检查,应该对所有入参场景生效,而不是只在单元素列表分支里执行
- 你在常规分支写的
lookup nameIn [cs]逻辑有误:lookup的作用是在关联列表中按键匹配值,这里的[cs]是把单个城市包成新的列表,不管目标城市名是什么,lookup的查找范围都只有这一个元素,完全达不到“在全量城市列表中查询目标城市”的设计目标。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

