You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在GHCi中声明函数时出现“Non exhaustive patterns in function”错误原因咨询

为什么GHCi中逐行定义Haskell函数会触发非穷尽模式错误,而加载模块却正常?

这个问题的核心差异在于GHC交互模式(GHCi)和模块编译模式对多模式函数定义的处理方式完全不同:

模块中的函数定义

在sum.hs模块里,你写的两行模式定义属于同一个函数的完整定义:

sum' :: (Num a) => [a] -> a
sum' [] = 0
sum' (x:xs) = x + sum' xs

GHC在编译模块时,会自动把这些模式分支合并成一个覆盖所有可能情况的函数:空列表直接返回0,非空列表则递归拆分计算。当递归到空列表时,能匹配到第一个分支,自然不会出现非穷尽模式的问题。

GHCi中的逐行定义

而在GHCi里,默认情况下,每一行单独的函数定义都会完全覆盖之前的同名函数,不是给已有函数补充模式分支:

  1. 输入第一行sum' [] = 0时,GHCi定义了一个仅处理空列表的sum'——这时候调用非空列表会报错,但调用空列表能正常返回0。
  2. 输入第二行sum' (x:xs) = x + sum' xs时,GHCi会直接替换掉之前的sum'定义,现在的sum'只有非空列表的处理逻辑,完全丢失了空列表的分支。

这时候调用sum' [3,4],函数会先匹配3:[4],计算3 + sum' [4];接着sum' [4]匹配4:[],计算4 + sum' [];但此时sum'没有定义空列表的处理分支,递归到这里就触发了非穷尽模式的异常——这就是你看到的错误。

如何在GHCi中正确定义多模式函数

如果想在GHCi中定义带有多个模式的函数,你需要把所有模式放在同一个输入块里,用:{和:}包裹:

Prelude> :{
Prelude| sum' [] = 0
Prelude| sum' (x:xs) = x + sum' xs
Prelude| :}
Prelude> sum' [3,4]
7

这样GHCi就会把这些行当作同一个函数的完整定义处理,和模块中的行为完全一致。

内容的提问来源于stack exchange,提问作者laker93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:02:37