xyncro / chiron

JSON for F#
https://xyncro.tech/chiron
MIT License
175 stars 41 forks source link

Question: how to 'drill in' with a JSON lens? #11

Closed haf closed 9 years ago

haf commented 9 years ago

I have a piece of data wrapped in an object naming it:

{"Voucher":{"@url":"https:\/\/
           ^^^ here starts the real object
^^^ wrapper object

I want to optionally 'unwrap' the outer object's property; what's the best way to do that?

kolektiv commented 9 years ago

Both this and #8 could definitely do with some good examples of lens use with JSON. I'll write a quick guide soon (although may be tomorrow now).

In essence, you'd want to combine the isomorphisms for wrapping and unwrapping the JSON type with the lens functions from core Aether. So in the case here where you want to make your "root" in to the object one level deep through the voucher key, you might do something like this...

let root =
         idLens
    <-?> Json.ObjectPIso
    >??> mapPLens "Voucher"
    <??> Json.ObjectPIso

That gives you a partial lens which is from the root JSON to a Map<string,Json> representing the object at "Voucher" (the last isomorphism would be different if the thing at "Voucher" wasn't an Object of course).

Lenses in to JSON can get quite verbose and it's worth creating them as parts and then composing them in different ways. At some point I might try and experiment with something like a JSONPath -> Lens type provider, although I'm not sure how possible that is in some senses!

haf commented 9 years ago

Nice, it worked!

haf commented 9 years ago

End code:

return singleOf resp (fun json ->
          match (fst voucherRoot) json with
          | None -> failwith "no Voucher object in result '%A'" json
          | Some vJson -> (Object vJson) |> (Json.deserialize : _ -> Voucher)
kolektiv commented 9 years ago

Cool :)

I think the (fst voucherRoot) bit could be Lens.getPartial, but that's probably a style choice to some extent :)

On 24 March 2015 at 09:55, Henrik Feldt notifications@github.com wrote:

End code:

return singleOf resp (fun json -> match (fst voucherRoot) json with | None -> failwith "no Voucher object in result '%A'" json | Some vJson -> (Object vJson) |> (Json.deserialize : _ -> Voucher)

— Reply to this email directly or view it on GitHub https://github.com/xyncro/chiron/issues/11#issuecomment-85428224.