如何避免带中缀构造器的递归类型派生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
相关产品推荐
相关产品推荐

