Haskell 漂亮的打印JavaScript对象
我选择将这个问题集中在JSON对象和()上,因为它们使MVCE变得容易,但我的问题实际上并不是简单地打印JSON对象,我可以灵活地选择使用哪个打印库Haskell 漂亮的打印JavaScript对象,haskell,pretty-print,Haskell,Pretty Print,我选择将这个问题集中在JSON对象和()上,因为它们使MVCE变得容易,但我的问题实际上并不是简单地打印JSON对象,我可以灵活地选择使用哪个打印库 考虑以下简化的JavaScript对象数据类型: data Object = Object [(String, Object)] | String String 我如何定义一个漂亮的打印函数,以通常的方式将其输出包装到多行?我的意思是:漂亮的打印输出应尽可能适合一行。如果不可能,我希望最外层的对象开始在内部对象之前添加换
考虑以下简化的JavaScript对象数据类型:
data Object = Object [(String, Object)]
| String String
我如何定义一个漂亮的打印函数,以通常的方式将其输出包装到多行?我的意思是:漂亮的打印输出应尽可能适合一行。如果不可能,我希望最外层的对象开始在内部对象之前添加换行符
下面是一个尝试,使用:
我希望最后的输出是
{
key5: { key1: "val1" },
key6: {
key2: "val2",
looooooooooong key3: "loooooooooooong val3",
key4: "val4"
},
key7: "val7"
}
我正在寻找一种与Haskell中现有的漂亮打印库(实际上,我打印的不仅仅是JSON的一个子集)相匹配的解决方案
我不是在寻找一种定义
prettyObject::Object->String
的解决方案-这种方法的全部要点是Doc
的呈现取决于它在漂亮打印的大图中的位置。您正在使用的漂亮打印库已经可以做到这一点;(你刚刚告诉它做一件不同的事情!)一般来说,这个漂亮的打印机家族(WL)很好地处理了这个问题
注意接头的位置
:
prettyObject (Object fields) = Union <one line> <many line>
您需要一个函数来实现所需的键值对逻辑:
indent' k x = flatAlt (indent k x) (flatten x)
prettyKVPair (k,v) = indent' 2 $ text k <> ":" <+> pretty v
注:没有明确的联合
,而是sep=group。vsep
和组=\x->联合(展平x)x
。现在,您有了一个联合,它对应于关于文本展开位置的逻辑选择
结果是:
>pretty o1
{ key1: "val1" }
>pretty o2
{
key2: "val2",
looooooooooong key3: "loooooooooooong val3",
key4: "val4"
}
>pretty o3
{
key5: "val5",
key6: {
key2: "val2",
looooooooooong key3: "loooooooooooong val3",
key4: "val4"
},
key7: "val7"
}
针对评论中的问题,提供平面替代方案的方法当然是使用
flatAlt
!这里唯一的问题是您希望对列表中的单个元素(最后一个)执行此操作,但这是列表的问题,而不是Doc
。您可以随意使用数据。序列
或任何其他可遍历的,标点
等大多数“类似列表”的功能都可以使用这些功能,如果这是一项您非常需要的操作的话
flattenedOf a b = flatAlt a (flatten b) # useful combinator
trailingSep _ [] = []
trailingSep s xs = as ++ [ (a <> s) `flattenedOf` a ]
where as = init xs; a = last xs
...
prettyObject (Object fields) = <unchanged> where
fields' = trailingSep "," $ <unchanged>
flattedof a b=flatAlt a(flatte b)#有用的组合器
trailingSep[]=[]
trailingSep s xs=as++[(as)`flattedof`a]
其中as=init xs;a=最后一个X
...
prettyObject(对象字段)=其中
字段“=trailingSep”,“$
非常感谢!这真是一个惊人的答案/解释。
indent' k x = flatAlt (indent k x) (flatten x)
prettyKVPair (k,v) = indent' 2 $ text k <> ":" <+> pretty v
prettyObject :: Object -> Doc a
prettyObject (Object fields) = sep $ "{" : fields' ++ [ "}" ] where
fields' = punctuate "," $ map prettyKVPair fields
...
>pretty o1
{ key1: "val1" }
>pretty o2
{
key2: "val2",
looooooooooong key3: "loooooooooooong val3",
key4: "val4"
}
>pretty o3
{
key5: "val5",
key6: {
key2: "val2",
looooooooooong key3: "loooooooooooong val3",
key4: "val4"
},
key7: "val7"
}
flattenedOf a b = flatAlt a (flatten b) # useful combinator
trailingSep _ [] = []
trailingSep s xs = as ++ [ (a <> s) `flattenedOf` a ]
where as = init xs; a = last xs
...
prettyObject (Object fields) = <unchanged> where
fields' = trailingSep "," $ <unchanged>