Here's a simplified version of an example on Argonaut's lens documentation:
import argonaut._, Argonaut._
val obj: Json = Parse.parseOption("""{"a":{"b":"x","c":2}}""").get
val lens1 = jObjectPL >=> jsonObjectPL("a") >=>
jObjectPL >=> jsonObjectPL("b") >=> jStringPL
lens1.mod(_ + "y", obj)
// res0: argonaut.Json = {"a":{"b":"xy","c":2}}
How do you do a similar thing with numeric fields? For example, suppose we wanted to add 1
to the number in obj
above, to get a result of
// res1: argonaut.Json = {"a":{"b":"x","c":3}}
My first attempt is to try
val lens2 = jObjectPL >=> jsonObjectPL("a") >=>
jObjectPL >=> jsonObjectPL("c") >=> jNumberPL
lens2.mod(_ + 1, obj)
But this last line doesn't compile.
JsonString
in Argonaut is simply a type alias for String
, but numbers are slightly more complicated because there is no core Scala type that can perfectly represent numbers in JSON.
The numeric type in Argonaut is JsonNumber
, so the type of the first argument passed to mod
needs to be (JsonNumber) => JsonNumber
.
The JsonNumber
subtypes with public constructors are:
JsonLong
JsonBigDecimal
JsonDouble
Here's a corrected version of the last line of code in the question, using JsonBigDecimal
:
lens2.mod(i => JsonBigDecimal(i.toBigDecimal + 1), obj)