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

启用OverloadedLists等扩展后GHC误报非穷举模式匹配错误排查

问题原因分析

这个问题的核心是同时启用OverloadedLists和RebindableSyntax扩展,且未显式导入列表构造器导致的GHC解析异常:

  • 启用RebindableSyntax后,GHC不会自动引入Prelude的默认语法绑定(包括列表构造器[]和(:)),而你的代码仅导入了Prelude的Int、IO、putStrLn,未包含这两个构造器。
  • 此时模式中的[]会被OverloadedLists解析为重载列表字面量(而非标准空列表构造器),GHC因此判定你没有真正匹配[Int]类型的空列表构造器,进而提示模式匹配非穷举。

解决方案

方案1:移除不必要的RebindableSyntax扩展

如果代码不需要该扩展,直接移除即可,GHC会正常识别列表构造器:

{-# LANGUAGE OverloadedLists #-}

import Prelude (Int, IO, putStrLn)
import GHC.Exts (IsList (..))

doneVsItems :: [Int] -> IO ()
doneVsItems [] = putStrLn "Done"
doneVsItems (p:ps) = putStrLn "Items"

main :: IO ()
main = doneVsItems []

方案2:显式导入列表构造器

若必须保留两个扩展,在Prelude的导入列表中添加[]和(:),让GHC识别标准列表构造器:

{-# LANGUAGE OverloadedLists, RebindableSyntax #-}

import Prelude (Int, IO, putStrLn, [], (:))
import GHC.Exts (IsList (..))

doneVsItems :: [Int] -> IO ()
doneVsItems [] = putStrLn "Done"
doneVsItems (p:ps) = putStrLn "Items"

main :: IO ()
main = doneVsItems []

方案3:改用null函数判断空列表

绕过模式匹配的语法问题,直接用null函数检查列表是否为空:

{-# LANGUAGE OverloadedLists, RebindableSyntax #-}

import Prelude (Int, IO, putStrLn, null)
import GHC.Exts (IsList (..))

doneVsItems :: [Int] -> IO ()
doneVsItems xs
  | null xs = putStrLn "Done"
  | otherwise = putStrLn "Items"

main :: IO ()
main = doneVsItems []

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 06:28:11