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

Haskell嵌套元组格式化:让渲染优先断开外层组softlines

如何让wl-pprint-annotated优先断开外层组的softlines来渲染嵌套元组?

我在用Haskell的wl-pprint-annotated库打印AST时遇到了嵌套元组的排版问题:渲染器总是优先断开内层组的softlines,而我希望外层元组先决定是否换行,内层元组跟着外层的排版策略走。

示例对比

以元组((1234, 5678), (abcd, efgh))为例:

期望输出:

// line width: 10
(
  (
    1234,
    5678
  ),
  (
    abcd,
    efgh
  )
)

// line width: 16
(
  (1234, 5678),
  (abcd, efgh)
)

// line width: 32
((1234, 5678), (abcd, efgh))

实际输出:

// line width: 10
((1234,
    5678),
  (abcd,
    efgh))

// line width: 16
((1234, 5678), (
    abcd, efgh))

// line width: 32
((1234, 5678), (abcd, efgh))

原代码

module Main where
import qualified Prelude
import Prelude hiding((<>))

import Text.PrettyPrint.Annotated.WL 

main :: IO ()
main = do
  putStrLn $ pp 10
  putStrLn $ pp 16
  putStrLn $ pp 32

pp w = "// line width: " ++ show w ++ "\n" ++
       display (renderPretty 1.0 w doc) ++ "\n"

doc = pair (pair (text "1234") (text "5678"))
           (pair (text "abcd") (text "efgh"))

pair x y = group (nest 2 (lparen <//> x <> comma </> y) <//> rparen)

解决方案

问题出在每个pair都被包装成独立的group,渲染器会从内到外评估每个组的换行可能性,优先尝试内层不换行,失败就断开内层。要让外层优先换行,我们需要调整组的结构,让外层的排版决策主导内层的行为:

修改pair的定义,用flatAlt指定紧凑排版和换行排版的两种分支,让外层的group主导整个元组的排版逻辑:

module Main where
import qualified Prelude
import Prelude hiding((<>))

import Text.PrettyPrint.Annotated.WL 

main :: IO ()
main = do
  putStrLn $ pp 10
  putStrLn $ pp 16
  putStrLn $ pp 32

pp w = "// line width: " ++ show w ++ "\n" ++
       display (renderPretty 1.0 w doc) ++ "\n"

doc = pair (pair (text "1234") (text "5678"))
           (pair (text "abcd") (text "efgh"))

pair x y = group $ 
  (lparen <+> x <> comma <+> y <+> rparen)
  `flatAlt`
  (lparen </> nest 2 (x <> comma </> y) </> rparen)

原理说明

  • flatAlt a b的作用是:如果当前上下文允许紧凑排版(即a能在剩余宽度内放下),就使用a;否则切换到换行排版的b。
  • 修改后的pair不再给内层元组单独设置group,而是让外层的group统一控制整个元组的排版。当外层需要换行时,内层元素才会跟着展开换行;外层能紧凑排版时,内层也保持紧凑。
  • 这种结构直接实现了“外层优先断开softlines”的需求,完全匹配期望的输出格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 01:36:33