如何使用 haskell 镜头重写 JSON 结构中的任意嵌套字段?
How can I rewrite an arbitrarily nested field in a JSON structure using haskell lenses?
我想通过以下测试:
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 like or transform,但我做不到,可能是对镜头的理解不够深入。
我设法使用以下代码更改了一个图层,但想将其用于嵌套字段。
rewrite' field value = value & key field %~ const "XXXXXXXX"
一种方法是使用 transformOn
along with 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")]))])
deep
在 Plated
结构中搜索所提供的 Traversal
匹配的位置,并且 transformOn
将更改应用于其每个目标。
编辑:
我刚刚意识到 transformOn
太过分了。您可以只使用 deep
和更简单的镜头组合器:
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*
函数族以递归方式应用其修改,这对于您要进行的修改来说太过分了。
我想通过以下测试:
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 like or transform,但我做不到,可能是对镜头的理解不够深入。
我设法使用以下代码更改了一个图层,但想将其用于嵌套字段。
rewrite' field value = value & key field %~ const "XXXXXXXX"
一种方法是使用 transformOn
along with 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")]))])
deep
在 Plated
结构中搜索所提供的 Traversal
匹配的位置,并且 transformOn
将更改应用于其每个目标。
编辑:
我刚刚意识到 transformOn
太过分了。您可以只使用 deep
和更简单的镜头组合器:
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*
函数族以递归方式应用其修改,这对于您要进行的修改来说太过分了。