When you call addToMyTupleList<'a>
, the concrete type of 'a
is statically known by the compiler (that is, you're calling addToMyTupleList<int>
, addToMyTupleList<float>
, etc.). By contrast, when you're trying to do the unboxing within Seq.iter
, you're hoping that 'a
will be determined based on the runtime type of the argument, which isn't how the F# type system works.
As I see it, you have a few options:
- Use a type test, as Daniel suggests.
- Instead of storing the raw values in the list, store the outputs you want to generate (that is, use a
string list
where you callsprintf
as you're putting things in. Be a bit more precise with the types you're storing in your list. Encode the type
∃'a.string * 'a
(that is, it's a pair consisting of a string and an'a
, for some unknown'a
) and store a list of these. In a language like Haskell this isn't too bad, but faithfully encoding it in F# is ugly/confusing:type ExPair<'x> = abstract Apply : string * 'a -> 'x type ExPair = abstract ForAll : ExPair<'x> -> 'x let pack p = { new ExPair with member __.ForAll<'x>(e:ExPair<'x>) : 'x = e.Apply p } let myList = [pack ("integer", 3) pack ("float", 3.0) pack ("string", "string") pack ("tuple", (3, "integer"))] myList |> List.map (fun e -> e.ForAll { new ExPair<string> with member __.Apply(s,x) = sprintf "%s,%A" s x })