json - 如何使用 Haskell Lens 重写 JSON 结构中的任意嵌套字段?

标签 json haskell haskell-lens aeson

我想通过以下测试:

it "can rewrite a field from an object" $ do
  let _42 = 42 :: Int
      nested =  object [ "foo" .= _42, "baz" .= object [ "bar" .= _42 ] ]
                                           ]
  rewrite "bar" nested  `shouldBe` object [ "foo" .= _42
                                          , "baz" .= object [ "bar" .= ("XXXXXXXX" :: Text) ]
                                          ]

看来我想要的是来自Control.Lens.Plated的东西,比如rewrite喜欢或transform但我无法让它发挥作用,可能是因为缺乏对镜头的深刻理解。

我设法使用以下代码更改单个层,但希望将其用于嵌套字段。

 rewrite' field value = value & key field %~ const "XXXXXXXX"

最佳答案

一种方法是使用transformOn以及deep精确控制变换的应用位置。

ghci> let nested = object [ "foo" .= 42, "baz" .= object [ "bar" .= 42 ] ]
ghci> transformOn (deep $ key "bar") (const "XXXXXXXX") nested
Object (fromList [("foo",Number 42.0),("baz",Object (fromList [("bar",String "XXXXXXXX")]))])

deepPlated 结构中搜索所提供的 Traversal 匹配的位置,并且 transformOn 将更改应用于它的每个目标。

编辑:

我刚刚意识到 transformOn 对此来说是巨大的杀伤力。您可以使用和更简单的镜头组合器:

ghci> deep (key "bar") %~ const "XXXXXXXX" $ nested
Object (fromList [("foo",Number 42.0),("baz",Object (fromList [("bar",String "XXXXXXXX")]))])

甚至

ghci> deep (key "bar") .~ "XXXXXXXX" $ nested
Object (fromList [("foo",Number 42.0),("baz",Object (fromList [("bar",String "XXXXXXXX")]))])

transform* 系列函数递归地应用其修改,这对于您想要进行的修改来说太过分了。

关于json - 如何使用 Haskell Lens 重写 JSON 结构中的任意嵌套字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44701870/

相关文章:

javascript - JSON 省略了 Infinity 和 NaN; ECMAScript 中的 JSON 状态?

Haskell 风格 : Pattern matching vs. 更直观的解决方案

haskell - Haskell 中函数组合的运行时

haskell - 如何使用镜头在嵌套 map 中设置值

json - 棱镜、遍历或折叠来自 readMaybe

haskell - 证明 Haskell Lens 库中断言的类型等效性的合理性

ios - Swift 中的 JSON 写入 (NSConcreteMutableData) 类型无效

javascript - 通过 AJAX 将 PHP 数据更改为 JS 数据(尤其是数组)时的最佳实践

javascript - "gameActivity" key 在开始时更改但应该停止

haskell - 将函数调用移动到 where 子句会破坏带有重叠实例的类型检查器