请求提供GHC记录语法下严格/非严格字段缺失的报错与警告示例
GHC对记录语法中严格/非严格字段遗漏的处理示例
没问题,我给你举两个具体的Haskell代码示例,清晰展示GHC的这个行为差异:
1. 遗漏严格字段:直接编译报错
首先定义一个包含严格字段的记录类型(严格字段用!标记,GHC要求必须显式赋值):
data StrictProfile = StrictProfile { fullName :: !String -- 严格字段,!表示必须立即求值 , age :: Int } deriving (Show)
如果构造值时遗漏这个严格字段:
-- 错误:遗漏了严格字段fullName invalidProfile :: StrictProfile invalidProfile = StrictProfile { age = 28 }
编译这段代码时,GHC会直接抛出编译错误,无法继续编译,错误信息类似:
Constructor ‘StrictProfile’ does not have the required field ‘fullName’
不管你有没有开启警告选项,这个错误都会触发——严格字段是编译期强制要求必须赋值的。
2. 遗漏非严格字段:仅发出编译警告
再定义一个包含非严格字段的记录类型(默认字段都是非严格的,不需要!):
data LazyProfile = LazyProfile { userName :: String -- 非严格字段,默认延迟求值 , userAge :: Int } deriving (Show)
如果构造值时遗漏这个非严格字段:
-- 警告:遗漏了非严格字段userName,但可以编译通过 lazyProfile :: LazyProfile lazyProfile = LazyProfile { userAge = 32 }
编译这段代码时(如果开启了-Wall等警告选项),GHC会发出警告,信息类似:
-Wmissing-fields: Missing field ‘userName’ in the record construction
程序依然可以编译成功,只是遗漏的字段会被填充为undefined——如果后续代码没有用到这个字段,程序能正常运行;如果用到了,才会在运行时触发异常。
简单总结:严格字段是编译期强制检查,必须赋值;非严格字段只是编译期警告,允许“偷懒”不赋值,但要承担运行时潜在的风险。
内容的提问来源于stack exchange,提问作者Marronnier
相关产品推荐
相关产品推荐

