为库中特定Type Class实例添加使用警告失败,WARNING编译指示无效
给Haskell的Show实例添加使用警告的正确方式
你遇到的问题是想让库的使用者在调用Foo的Show实例时触发警告,对吧?之前尝试WARNING编译指示没成功,大概率是因为用法不对——WARNING默认是编译模块时触发,而你需要的是使用者调用该实例方法时触发警告,这时候应该用DEPRECATED编译指示,或者调整WARNING的作用范围。
下面是两种可行的方案:
方案1:针对show方法添加废弃警告
直接给实例里的show方法标记为废弃,这样只要使用者调用show Foo,编译器就会弹出警告。代码示例:
data Foo = Foo instance Show Foo where {-# DEPRECATED show "不建议使用Foo的Show实例,请使用自定义的myFooDisplay函数替代" #-} show _ = "Foo"
这种方式的好处是精准触发——只有当实际调用show(也就是用到这个实例的核心方法)时才会警告,导入模块但不使用的话不会有提示。
方案2:给整个Show实例添加警告
如果你希望只要使用者导入这个实例(哪怕暂时没调用)就触发警告,可以用WARNING编译指示放在实例定义上方:
data Foo = Foo {-# WARNING "Foo的Show实例仅用于内部调试,请勿在生产代码中使用" #-} instance Show Foo where show _ = "Foo"
不过要注意,这种方式是在编译使用者的代码时,只要导入了包含这个实例的模块就会触发警告,不管有没有实际使用。
关键注意事项
- 要让使用者看到这些警告,他们必须开启对应的编译选项:比如
-Wall(开启所有常见警告),或者单独开启-Wdeprecated(针对废弃警告)、-Wwarnings-deprecations。如果使用者没开这些选项,警告不会显示出来。 - 建议在警告信息里明确告诉使用者应该用什么替代方案(比如自定义的显示函数),这样体验更好。
举个实际的测试场景:当使用者写了main = print Foo,开启-Wall编译时,就会看到类似这样的警告:
Warning: show is deprecated: 不建议使用Foo的Show实例,请使用自定义的myFooDisplay函数替代
这样就能达到你想要的效果啦!
内容的提问来源于stack exchange,提问作者user2882307
相关产品推荐
相关产品推荐

