问题描述
我正在使用 prettyprinter
库来漂亮打印 foo(bar,baz)
,当边距太窄时,我希望它看起来像:
foo(
bar,baz)
我该怎么做?
迄今为止我的最佳尝试:
> import Prettyprinter
> import Prettyprinter.Util
> let commas = punctuate comma
-- 'sep' and 'nest' seem to go well together,but the result lacks the linebreak
> putDocW 10 ("foo" <> parens (nest 2 (sep (commas ["bar","baz"]))))
foo(bar,baz)
-- Using 'line'' inside 'nest' almost does the trick
> putDocW 10 ("foo" <> parens (nest 2 (line' <> sep (commas ["bar","baz"]))))
foo(
bar,baz)
-- Except 'line'' doesn't seem "mempty" enough
> putDocW 20 ("foo" <> parens (nest 2 (line' <> sep (commas ["bar",baz)
因为提到了mempty
,我以为我想要的是line'
:
line'
类似于 line
,但如果由 mempty
(而不是 group
)撤消换行符,则其行为类似于 space
。
但也许我误解了“由 group
撤消”的含义。
其他(line
、softline
和 softline'
)似乎都没有提供更好的结果。
解决方法
我不确定这是“正确”的方式,但有一个方法:
COMPLEX
也就是说,将左括号和标点元素的串联挂在前缀后面,根据它们是否折叠,用或不用尾随空格将它们分开,并附加在右括号上。
或者,您可以制作自己的 hcat
[ "prefix",nest 2 $ cat
$ "("
: punctuate (flatAlt "," ",")
[ "first","second","third"
],")"
]
变体,在末尾而不是开头添加分隔符,并在 encloseSep
中包含开始分隔符:
cat
encloseSepEnd
:: Doc ann -> Doc ann -> Doc ann -> [Doc ann] -> Doc ann
encloseSepEnd open close sep docs = case docs of
[] -> open <> close
[doc] -> open <> doc <> close
_ -> cat (open : suffixReverse (close : repeat sep) docs)
suffixReverse
:: (Foldable t,Semigroup a)
=> [a] -> t a -> [a]
suffixReverse separators
= snd . foldr go (separators,[])
where
go doc (sep : seps,acc) = (seps,doc <> sep : acc)
除此之外,老实说,我发现我总是不得不将 hcat
[ "prefix",nest 2 $ encloseSepEnd "(" ")" ","
["first","third"]
]
之类的括号函数替换为其单独的部分,以实现我想要的结果,而 parens
从来没有按照我希望的方式行事。