2016-06-21 7 views
2

は、次のような単純なJSONドキュメントを想定します。さて、それを行うには、前方可能とストレートで以下のようにHCursorを使用して:argonautレンズを使用してJSONで値と型を変更するにはどうすればよいですか?文字列からint型に変更して、私は、「キー」の値を更新したいが、同時にまた、そのタイプを変更したい</p> <pre><code> { "key" : "val1" } </code></pre> <p>:

val cursor = js.hcursor 
val position = (cursor --\ "key") >-> (_ => jNumber(1)) 

「元に戻す」ことで、私は「キー」は、数値ではなく文字列を持つ新しいJSONを持つ終わる上記の位置をこれは完璧です。

レンズでも同じことができますか?私は次の操作を行うことを試みた:

val lense = jObjectPL >=> 
      jsonObjectPL("key") >=> 
      jNumberPL 
lense.mod(_ => JsonBigDecimal(1), js) 

しかし、私は、それはまた、動作しないエラーを得ることはありませんが、最後に私が変更されていないオリジナルのJSON文書で終わります。しかし、私がデータ型を尊重すれば、物事は彼らのように機能します。同じデータ型の変更にのみレンズを使用すべき理由はありますか?または、私はちょうどひどく間違って何かをしています:)

答えて

4

いいえ、ひどく間違っている - あなたはほとんどそこにいる。 "key"でJSON番号へ

jObjectPL >=> jsonObjectPL("key") >=> jNumberPL 

ナビゲート:問題は、このパスです。 jsにはキーにJSON番号がないため、レンズは何も指しておらず、変更は何にも影響しません。

あなただけのレンズからの最後のステップを削除することによってこの問題を解決することができます

val lens = jObjectPL >=> jsonObjectPL("key") 

これはちょうど"key"フィールドに移動したが、それはJSON値の種類に制約をかけていません。そして、あなたが好きにそれを変更することができます。レンズはJson値を指していることから、ないJsonNumber、あなたはタイプがラインアップさせるためにjNumberJsonBigDecimalをラップする必要がありますことを

scala> val lens = jObjectPL >=> jsonObjectPL("key") 
lens: scalaz.PLensFamily[... 

scala> lens.mod(_ => jNumber(JsonBigDecimal(1)), js) 
res0: argonaut.Json = {"key":1} 

注意を。

+0

@Travisをお返事ありがとうございます!とても有難い。レンズとArgonautのドキュメントを読む私は、あなたが期待する種類のJSONデータ型を常に定義する必要があるという印象を受けました。しかし、それは人間の本質の一部だと思ういくつかのことを複雑に過ぎる:) – cpard

+0

@cpardねえ:)。この場合、その位置にJSON文字列が必要ですが、 'jStringPL'をレンズに追加すると、そのタイプを変更することはできません。 –

関連する問題

 関連する問題