Programming 101: if you repeat the same thing over and over, pack it for reuse, make it a function. In your case, the function will be general (i.e., it will take a parameter of any type) and make upcast by parameter:
let pair name value = name, value :> obj myfun [pair "Name" "Freddie"; pair "Age" 50]
Hmm ... Not much nicer, is it? But wait, we're not done yet! Now that you have this feature, you can give it a nicer name that will make it nicer. Let's say ==> :
let (==>) name value = name, value :> obj myfun ["Name" ==> "Freddie"; "Age" ==> 50]
If your set of possible types is known in advance and relatively small (as your question indicates), you can take one more step and check the compiler that only allowed types are used. To do this, you need to use method overloads, static type constraints, and some syntax tricks:
type Casters() = static member cast (v: string) = v :> obj static member cast (v: float) = v :> obj static member cast (v: int) = v :> obj static member cast (v: string list) = v :> obj static member cast (v: float list) = v :> obj static member cast (v: int list) = v :> obj let inline cast (casters: ^c) (value: ^t) = ( (^c or ^t) : (static member cast : ^t -> obj) value) let inline (==>) name value = name, (cast (Casters()) value) ["Name" ==> "Freddie"; "Age" ==> 50]
source share