Closed jackmott closed 8 years ago
Hi @jackmott - this is a little bit fiddly, as the Json functions are stateful (state monads, basically). Therefore to "map" over a collection like that you'd actually need to fold, passing the Json state along as you went. For the simple case of doing this, you could have a function like this, which would act as a generic fold, and apply more Json functions to the current state:
[<RequireQualifiedAccess>]
module Json =
let fold (f: _ -> Json<_>) xs : Json<unit> =
fun json ->
Value (), List.fold (fun json x ->
snd ((f x) json)) json xs
We're throwing away return values of Json<_>
functions as we're assuming that our functions succeed (a safe enough bet for this kind of thing). Now in your case you could use this Json.fold
function where your for
currently is - like this:
type EffortData =
{ lap: int
distance: distance
splits: SplitTracker [] }
static member ToJson (x:EffortData) =
Json.write "lap" x.lap
*> Json.write "distance" (x.distance.ToString())
*> Json.fold (fun x -> Json.write x.name x.duration) x.splits
That should (if I've understood, sorry if I haven't!) give you the result you're looking for I think. Hope this helps!
Spectacular, thank you.
No problem :smile: I'll close this for now - feel free to comment again if you need anything and I'll re-open!
So as written fold is expecting a Json<'a> []
but is being given a SplitTracker []
, probably something simple to resolve if I understood the fold function better, but I am still learning F#.
Oh, hmmm. Seemed to work for me with a faked test, is it not working for you? If you want to paste some code in somewhere (maybe a gist) I can take a look.
I figured it out, type inference was picking up on a different type with some of the same names. Annotating the type fixed it up. Thank you!
Cool :smile: From the type names, sounds like you're working on something fun...
I would like to 'flatten' the json output of a nested type when serializing to json. To illustrate what I mean, below is the the logic I would like to express:
How can I accomplish this?