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

如何消除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:10:52