2017-06-22 14 views
2

私は、次のテストパスを作成したいと思います:haskellレンズを使用してJSON構造内の任意のネストされたフィールドを書き換えるにはどうすればよいですか?

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) ] 
              ] 

私がしたいことのようrewriteまたはtransformようControl.Lens.Platedから何かがあるようだが、私はそれはおそらくの深い理解が欠けに、動作させるために管理することはできませんレンズ。

次のコードを使用して1つのレイヤーを変更することはできましたが、ネストされたフィールドにそのレイヤーを利用したいと考えています。

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

'\ field - > transform( 'field'を書き換えます)は何をしますか? (ちょうど推測 - 私はレンズの専門家でもない) – user2407038

答えて

2

一つのアプローチは、変換が適用された場合の正確な制御を得るためにdeepと共にtransformOnを使用することです。

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設けTraversalマッチ位置についてPlated構造を検索し、transformOn、そのターゲットのそれぞれに変更を適用します。

EDIT:

私はちょうど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*家族は、あなたがしたいの変更のためのやり過ぎである、再帰的にその変更を適用します。

関連する問題