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

如何为含多构造器与模式同义词的类型编写COMPLETE编译指示?

使用COMPLETE编译指示自动覆盖构造器与模式同义词

要解决手动枚举构造器易遗漏的问题,你可以利用GHC的COMPLETE编译指示结合通配符或类型引导,同时配合废弃标记区分被替换的构造器。

核心方案:通配符+废弃标记

假设你有一个包含大量构造器的类型,以及用于替换部分构造器的模式同义词:

-- 定义包含多构造器的类型
data BigType = A Int | B String | C Bool | D Double | E Char
-- 后续可能新增F、G等构造器

-- 定义替换构造器的模式同义词
pattern MyA :: Int -> BigType
pattern MyA x = A x

pattern MyB :: String -> BigType
pattern MyB s = B s

步骤1:用通配符自动包含所有构造器

使用..通配符指代BigType的所有构造器,再加上你的模式同义词,编写COMPLETE编译指示:

{-# COMPLETE MyA, MyB, .. #-}

这里的..会自动包含BigType的所有构造器(包括后续新增的),配合MyA和MyB组成完整的模式匹配集。

步骤2:标记被替换的构造器为废弃

为避免用户误用原构造器(比如A、B),用DEPRECATED编译指示标记它们:

{-# DEPRECATED A "请使用模式同义词MyA替代" #-}
{-# DEPRECATED B "请使用模式同义词MyB替代" #-}

这样当有人直接使用A或B时,GHC会抛出警告,引导他们使用对应的模式同义词。

进阶方案:类型类引导(无命名规律场景)

如果构造器没有统一命名规律,且需要更精确控制完整集,可以用类型类标记需要包含的模式:

步骤1:定义标记用类型类

class CoversBigType p

这个类不需要任何方法,仅用于标记哪些模式属于完整匹配集。

步骤2:为模式同义词和保留的构造器创建实例

-- 为模式同义词的类型创建实例
instance CoversBigType (Int -> BigType)   -- 对应MyA
instance CoversBigType (String -> BigType) -- 对应MyB

-- 为保留的构造器类型创建实例
instance CoversBigType Bool   -- 对应C
instance CoversBigType Double -- 对应D
instance CoversBigType Char   -- 对应E

后续新增构造器时,只需为其类型添加对应的CoversBigType实例即可,无需修改COMPLETE指示。

步骤3:指定COMPLETE编译指示

{-# COMPLETE CoversBigType #-}

GHC会自动将所有实现CoversBigType的模式和构造器视为完整匹配集。

注意事项

  • ..通配符仅在GHC 8.10及以上版本支持;
  • 模式同义词默认是双向的(可用于模式匹配和表达式),若用<-定义则为单向模式,仅能用于匹配;
  • 新增构造器时,通配符方案无需修改COMPLETE;类型类方案只需添加对应实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:50:26