如何消除Getter中的‘Redundant constraint: Functor f’警告?
问题
定义了SomeRecord记录及_user、_password字段,想要为形如<user>:<password>的“虚拟”字段编写Getter,代码如下:
identity:: Getter SomeRecord String identity = to $ \srec -> srec^.user <> ":" <> srec^.password
但这段代码触发了如下警告:
• Redundant constraint: Functor f • In the type signature for: identity :: Getter SomeRecord Stringtypecheck(-Wredundant-constraints)
请问该Getter存在什么问题?如何编写才能避免该警告?
补充信息
找到相关讨论内容:
(ekmett 评论)
为了避免被 GHC 8 的 lens 用户投诉淹没,我们可能会直接给to加上这个约束,然后靠{-# INLINE #-}在实际编译时把它去掉。这种场景太常见了,值得我们自己承担这份“噪音”。
当然,如果你把不遵守定律的遍历器声明为折叠器之类的,也会遇到同样的问题。这种情况下恐怕只能禁用警告了——GHC 没法识别“定律”。
原因与解决方案
问题根源
这个警告来自Getter类型和to函数的类型不匹配:Getter s a的底层类型包含Functor f约束,但通过to构造的Getter本质是纯函数转换,根本不需要这个函子约束。GHC的冗余约束检查能检测到这一点,因此抛出警告。
解决办法
1. 调整类型签名或去掉签名
- 直接去掉显式类型签名,让GHC自动推导更精确的类型(无冗余约束):
identity = to $ \srec -> srec^.user <> ":" <> srec^.password - 若需要显式签名,改用
Getting类型(Getter的超类型,无冗余约束):identity :: Getting String SomeRecord String identity = to $ \srec -> srec^.user <> ":" <> srec^.password
2. 局部禁用警告
如果必须保留Getter类型签名,可以在代码中局部关闭冗余约束警告:
{-# OPTIONS_GHC -Wno-redundant-constraints #-} identity:: Getter SomeRecord String identity = to $ \srec -> srec^.user <> ":" <> srec^.password
或者仅针对该函数禁用:
{-# ANN identity ("HLint: ignore Redundant constraint" :: String) #-} identity:: Getter SomeRecord String identity = to $ \srec -> srec^.user <> ":" <> srec^.password
3. 改用纯函数(可选)
如果只是需要获取虚拟字段的值,完全可以定义一个普通纯函数,没必要用Getter:
identity :: SomeRecord -> String identity srec = srec^.user <> ":" <> srec^.password
使用时直接调用identity record,和用record^.identity效果一致。
内容的提问来源于stack exchange,提问作者RandomB
相关产品推荐
相关产品推荐

