samedi 17 octobre 2020

How can I determine the json path to a field within a record without actually hard coding the path?

I would like to work with the following type

type RecordPath<'a,'b> = {
    Get: 'a -> 'b
    Path:string
}

It's purpose is to define a getter for going from record type 'a to some field within 'a of type 'b. It also gives the path to that field for the json representation of the record.

For example, consider the following fields.

type DateWithoutTimeBecauseWeirdlyDotnetDoesNotHaveThisConcept = {
    Year:uint
    Month:uint
    Day:uint
}

type Person = {
    FullName:string
    PassportNumber:string
    BirthDate:DateWithoutTimeBecauseWeirdlyDotnetDoesNotHaveThisConcept
}

type Team = {
    TeamName:string
    TeamMembers:Person list
}

An example RecordPath might be

let birthYearPath = {
    Get = fun (team:Team) -> team.TeamMembers |> List.map (fun p -> p.BirthDate.Year)
    Path = "$.TeamMember[*].BirthDate.Year" //using mariadb format for json path
}

Is there some way of letting a library user create this record without ever actually needing to specify the string explicitly. Ideally there is some strongly typed way of the user specifying the fields involved. Maybe some kind of clever use of reflection?

It just occurred to me that with a language that supports macros, this would be possible. But can it be done in F#?

PS: I notice that I left out the s in "TeamMembers" in the path. This is the kind of thing I want to guard against to make it easier on the user.





Aucun commentaire:

Enregistrer un commentaire