If your function was to apply an arbitrary function f to an arbitrary element of a tuple, for example, the function f is of the correct type, then you could make this polymorphism to some extent.
In other words, if you think about what you can do with your function, you will come to the conclusion that you will need a function of the correct type to apply it to the result of nth_diff_type , regardless of what the type may be.
If we assume for a moment that nth_diff_type works with any tuple, its result is potentially any type. You can get int , a string or instances of more complex data types. Let me call this type t . Then what can you do with a value of type t ? You can only pass it to a function that takes t values.
So, now the problem is choosing the right function, and this choice will certainly be made according to very similar criteria than the rank of the element inside your tuple. If so, why not just pass in your tuple and tuple of functions that could be applied to nth_diff_type and let it make the application on its own?
let nth_diff_type i (a,b,c) (fa,fb,fc) = match i with | 1 -> fa a | 2 -> fb b | 3 -> fc c | _ -> failwith "out of range" -: val nth_diff_type : int -> ( 'a * 'b * 'c) -> (('a -> 'd) * ('b -> 'd) * ('c -> 'd)) -> 'd
source share