使用 lens-aeson 提取 JSON 场时结合棱镜
Combining prisms when extracting JSON fields with lens-aeson
我有一个 JSON 类似于以下内容的 blob:
[
{
"version": 1
},
{
"version": "3"
},
...
]
请注意,有些版本是数字,有些是字符串。
我想获取版本列表。
我可以使用以下镜头组合来提取数字版本:
v1 :: [String]
v1 = obj ^.. AL.values . AL.key fieldName . AL._Number . to show
然后提取字符串
v2 :: [String]
v2 = obj ^.. AL.values . AL.key fieldName . AL._String . to T.unpack
但是,如何通过单次遍历列表来获取版本列表?
是否有任何镜头组合器将镜头 AL._Number . to show
和 AL._String . to T.unpack
和 returns 组合成 getter 以便如果第一个失败,请尝试第二个?像 msum
这样的镜头?
实际上有一个组合器尝试光学器件并在第一个失败时转到备份。它被称为 failing。
请注意,您所描述的情况应满足其条件。即使不是,组合器仍然可以运行,只是在重构时表现不规则。 (这是使用 filtered 作为 Traversal
的主要问题。)
在 , which is what you should use, I was going to suggest outside
之前作为使用这些棱镜进行案例分析的一种方式:
tryNumberThenString :: AL.AsPrimitive t => t -> [String]
tryNumberThenString =
outside AL._Number .~ (:[]) . show $
outside AL._String .~ (:[]) . T.unpack $
const []
v1 = obj ^.. AL.values . AL.key fieldName . folding tryNumberThenString
请注意,除非我遗漏了一些其他技巧,否则这不仅比 Carl 所建议的更复杂,而且更不灵活——我只能从普通函数 tryNumberThenString
,而 failing
将棱镜组合成 Traversal
。
我有一个 JSON 类似于以下内容的 blob:
[
{
"version": 1
},
{
"version": "3"
},
...
]
请注意,有些版本是数字,有些是字符串。 我想获取版本列表。 我可以使用以下镜头组合来提取数字版本:
v1 :: [String]
v1 = obj ^.. AL.values . AL.key fieldName . AL._Number . to show
然后提取字符串
v2 :: [String]
v2 = obj ^.. AL.values . AL.key fieldName . AL._String . to T.unpack
但是,如何通过单次遍历列表来获取版本列表?
是否有任何镜头组合器将镜头 AL._Number . to show
和 AL._String . to T.unpack
和 returns 组合成 getter 以便如果第一个失败,请尝试第二个?像 msum
这样的镜头?
实际上有一个组合器尝试光学器件并在第一个失败时转到备份。它被称为 failing。
请注意,您所描述的情况应满足其条件。即使不是,组合器仍然可以运行,只是在重构时表现不规则。 (这是使用 filtered 作为 Traversal
的主要问题。)
在 outside
之前作为使用这些棱镜进行案例分析的一种方式:
tryNumberThenString :: AL.AsPrimitive t => t -> [String]
tryNumberThenString =
outside AL._Number .~ (:[]) . show $
outside AL._String .~ (:[]) . T.unpack $
const []
v1 = obj ^.. AL.values . AL.key fieldName . folding tryNumberThenString
请注意,除非我遗漏了一些其他技巧,否则这不仅比 Carl 所建议的更复杂,而且更不灵活——我只能从普通函数 tryNumberThenString
,而 failing
将棱镜组合成 Traversal
。