Given the JsonExample in the monocle project, I would like to create a lens where a set call will either replace a value in a key/value pair, or create the key/value pair if it doesnt already exist.
However this seems to represented with either an index (which can compose type safe) or an at, which does not type safe
//for replacing:
(jsObject composeOptional index("age") composePrism jsNumber).set(45)
//for creating:
(jsObject composeLens at("age")).set(JsNumber(45)) <- will accept any old json
Is what I am after possible?
Also could I extend it, such that if age was nested in another JsObject, for example:
val n = (jsObject composeOptional index("nested") composePrism
jsObject composeOptional index("age") composePrism jsNumber).set(45)
Where the key/value pair for "nested" didnt yet exist, that it would create the object at nested and then add the field
n(JsObject(Map.empty)) -> JsObject(Map("nested" -> JsObject("age" -> JsNumber(45)))
let's have a look at
index
andat
signature forJsObject
:at
is aLens
so its target ('Option[Json]') is always present. It means that we canadd
,delete
andupdate
theJson
element at any field of aJsonObject
.On the other hand,
index
is anOptional
so it is target (Json
) may or may not be there. It means thatindex
can onlyupdate
values but cannotadd
ordelete
.So to come back to your original question, if you want to
add
orupdate
value at a particular field, you need to useat
and wrap theJson
in aSome
(seeres1
), it will overwrite or create theJson
at that field.