Reputation: 2896
I expected the two following snippets to both work, but the F# one fails to find an overload for SelectMany
//C#
var aaa = new Dictionary<string, List<string>>();
Func<KeyValuePair<string, List<string>>, List<string>> fff = (KeyValuePair<string, List<string>> kvp) => kvp.Value;
var bbb = aaa.SelectMany(fff);
//F#
let aaa = new Dictionary<string, List<string>>()
let fff = Func<_, _>(fun (kvp:KeyValuePair<string, List<string>>) -> kvp.Value)
let bbb = aaa.SelectMany(fff) //Error FS0041 No overloads match for method 'SelectMany'
Does anyone know why? Notice that fff have the same type in both snippets
Upvotes: 0
Views: 137
Reputation: 2896
My question is about "why" not "how". the other answers gave the solution indirectly, however the answer to the original question is like:
" SelectMany expects a function returning IEnumerable<>, while fff returns List<>. C# allows using fff directly by implicitly cast, F# is stricter and requires an explicit cast"
Upvotes: 0
Reputation: 17038
It looks like F# requires you to explicitly cast the return type to IEnumerable<_>
, so this will work:
let aaa = new Dictionary<string, List<string>>()
let fff = Func<_, _>(fun (kvp:KeyValuePair<string, List<string>>) -> kvp.Value :> IEnumerable<_>)
let bbb = aaa.SelectMany(fff)
Or, more simply:
let aaa = new Dictionary<string, List<string>>()
let bbb = aaa.SelectMany(fun kvp -> kvp.Value :> IEnumerable<_>)
However, as mentioned above, using the Seq
module instead of LINQ is much more idiomatic in F#.
Upvotes: 2