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

如何避免带中缀构造器的递归类型派生Show时生成冗余括号

问题

针对如下自定义列表类型:

data WithInfixR a = a :> WithInfixR a | Rightmost
  deriving Show
infixr 4 :>

自动派生的Show实例会给递归值添加不必要的括号,示例如下:

ghci> 0 :> 1 :> 2 :> Rightmost
0 :> (1 :> (2 :> Rightmost))

请问是否存在无需自行实现Show实例的方法,来去除这些冗余括号?


回答

很遗憾,没有办法仅靠自动派生的Show实例去掉这些冗余括号。

Haskell自动派生的Show实例处理中缀构造器时,不会识别你声明的fixity(结合性与优先级)——它只会给所有递归嵌套的子项统一添加括号,完全不判断是否必要。

如果想要得到无冗余括号的输出,必须手动实现Show实例,就像你提供的参考代码那样:

instance Show a => Show (WithInfixR a) where
  showsPrec p Rightmost = showString "Rightmost"
  showsPrec p as = showParen (p >= 4) (showsWithInfixR as) where
    showsWithInfixR :: forall a. Show a => WithInfixR a -> ShowS
    showsWithInfixR = \case
      a :> as   -> showsPrec 4 a . showString " :> " . showsWithInfixR as 
      Rightmost -> showString "Rightmost"

这个手动实现通过showsPrec结合构造器的优先级(infixr 4)来判断是否需要添加括号,从而输出简洁的无冗余格式。


内容的提问来源于stack exchange,提问作者rampion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:44:54