Given a trivial sequence of tuples, and a parallel one using F# PowerPack's PSeq:
let a = Seq.singleton (1,"a") --> val a: seq<int * string>
let b = a |> PSeq.map id --> val b: pseq<int * string>
Now I'd like to create a .Net BCL dictionary from them:
let bd = b.ToDictionary(fst, snd, HashIdentity.Structural)
let ad = a.ToDictionary(fst, snd, HashIdentity.Structural)
let ad2 = a.ToDictionary(fst, snd)
let ad3 = a.ToDictionary((fun (x,y) -> x), (fun (x,y) -> y), HashIdentity.Structural)
While let bd works, let ad does not compile as it fails to infer types and convert to BCL's Func correctly. Interestingly it works just fine if I omit the third parameter, as in let ad2, or if I write out fst and snd manually inline as in let ad3.
This expression was expected to have type Func<(int * string),'a> but here has type 'b * 'c -> 'b
- Why does
let adnot compile, while all the alternatives work fine? - Is there a way to make
let adcompile, without providing inline functions or type annotations?
PS: I need HashIdentity.Structural because in the real code the keys are not integers but tuples or records
Update: I've now defined let dictionary (s : ('a * 'b) seq) = s.ToDictionary((fun (x,y)->x), (fun (x,y)->y), HashIdentity.Structural) so I can just write let ad = a |> dictionary, but I'm still interested in why it won't compile with the fst and snd functions.
dict. See @Daniel's answer for an example. - Jack P.