Nested F# Record with generic type parameter, how do I statically cast between types in nested structure equivalent to traversing and performing 'T |> 'K, e.g. float |> int?
Currently I am Naively traversing the nested records and explicitly converting the type with from:float |> to:int or equivalently int(from). However, this is not very beautiful.
type Person<'T> = {Id : int; Value : 'T}
type Family<'T> = {Id : 'T; People : seq<Person<'T>>}
let fam1 = {Id = 1.0; People = [{Id = 1.1; Value = 2.9}; {Id = 1.2; Value = 4.4}]} : Family<float>
let fam2 = {Id = 2.0; People = [{Id = 2.1; Value = 3.9}; {Id = 2.2; Value = 5.4}]} : Family<float>
let partyFloat = seq{ yield fam1; yield fam2}
// In general, how to do this from a type T to a type K where conversion using T |> K will work
let partyInt : seq<Family<int>> = partyFloat
How to statically and/or
lazily convert to seq<Family<int>>?
In my real world case I have a DiffSharp D type that can be converted to a float with D |> float or float(D).
There is no magic way to cast the insides of types, you have to write your own.
It is idiomatic for F# and functional programming in general (and I personally recommend it, too) to write small functions for simple data transformations, and then assemble them together:
let mapPerson f p = { Id = p.Id; Value = f p.Value }
let mapFamily f fm = { Id = f fm.Id; People = Seq.map (mapPerson f) fm.People }
let mapParty f = Seq.map (mapFamily f)
let partyInt = mapParty int partyFloat
But of course you can do it in one big messy go:
let partyInt =
partyFloat
|> Seq.map (fun fm ->
{ Id = int fm.Id
People =
fm.People
|> Seq.map (fun p ->
{ Id = p.Id; Value = int p.Value }
)
}
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With