如何抑制同构于Void的记录字段的未赋值警告?
Haskell记录类型字段未初始化警告的针对性抑制问题
问题背景
我定义了如下数据类型:
data File' key generated value = File { id :: key Int, md5Hash :: generated Text, contents :: value Text, description :: value Text -- 省略其他字段 }
基于这个类型,我定义了几个业务场景对应的类型别名:
type FileCreate = File' (Const Void) (Const Void) Identity type FileUpdate = File' Identity (Const Void) Maybe type FileLookup = File' Identity (Const Void) (Const Void) type File = File' Identity Identity Identity
核心矛盾
当创建FileLookup类型实例时,写FileLookup { id = Identity 1234 }会触发未赋值记录字段的警告。但这些未赋值的字段都是Const Void类型——这种类型没有合法构造值,本来就不需要赋值。
但我不能全局关闭这类警告,因为像FileCreate { description = Identity "This file hasn't had 'contents' assigned so this should be an error" }这种遗漏必填字段的情况,必须靠警告来及时发现问题。
现有方案的缺陷
我尝试过两种解决思路,但都不尽如人意:
- 编写场景专用的构造函数,比如
fileCreate :: Text -> Text -> FileCreate、fileUpdate :: Int -> Text -> Text -> FileUpdate、fileKey :: Int -> FileLookup。但这会生成大量重复样板代码,还丢失了记录语法的便捷性。 - 利用GHC的
record patterns扩展创建专用模式同义词。但每个数据类型都要定义3-4个对应模式,样板代码的工作量依然很大。
实际需求与理想方案
我实际项目中有很多类似File的数据类型,但操作模式只有约5种(插入、更新、查询等)。我愿意为这些模式编写少量通用样板,但不想为每个数据类型重复造轮子。可以接受使用Generics,尽量避免用Template Haskell。
理想状态是能有类似这样的编译指示:
{-# PRAGMA DontWarnIfThisParticularTypeOrANewtypeOfThisParticularTypeIsNotInitialisedInARecord #-} data MyConstVoid a -- 无构造函数
用MyConstVoid替代Const Void,从而针对性地抑制这类字段的未初始化警告,但目前找不到这种实现方式。
内容的提问来源于stack exchange,提问作者Clinton
相关产品推荐
相关产品推荐

