【问题标题】:F# - using Linq SelectMany on dictionary doesn't work as expectedF# - 在字典上使用 Linq SelectMany 不能按预期工作
【发布时间】:2021-02-16 07:22:53
【问题描述】:

我希望以下两个 sn-ps 都可以工作,但 F# 找不到 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'

有人知道为什么吗?请注意,fff 在两个 sn-ps 中具有相同的类型

【问题讨论】:

  • 可用重载: - (extension) IEnumerable.SelectMany(selector: Func>) : IEnumerable // 参数 ' selector' 不匹配 - (extension) IEnumerable.SelectMany(selector: Func>) : IEnumerable // 参数 'selector' 不匹配'不匹配
  • LINQ 在 F# 代码库中非常少见,因为有 Seq 模块允许使用更惯用的代码做同样的事情。考虑使用Seq.collect
  • @JL0PD 问题不是“如何做到这一点”,而是“为什么会这样”。

标签: c# generics f#


【解决方案1】:

看起来 F# 要求您将返回类型显式转换为 IEnumerable&lt;_&gt;,所以这将起作用:

let aaa = new Dictionary<string, List<string>>()
let fff = Func<_, _>(fun (kvp:KeyValuePair<string, List<string>>) -> kvp.Value :> IEnumerable<_>)
let bbb = aaa.SelectMany(fff)

或者,更简单地说:

let aaa = new Dictionary<string, List<string>>()
let bbb = aaa.SelectMany(fun kvp -> kvp.Value :> IEnumerable<_>)

但是,如上所述,在 F# 中使用 Seq 模块而不是 LINQ 更为惯用。

【讨论】:

    【解决方案2】:

    我的问题是关于“为什么”而不是“如何”。其他答案间接给出了解决方案,但原始问题的答案如下:

    " SelectMany 期望函数返回 IEnumerable,而 fff 返回 List。C# 允许通过隐式转换直接使用 fff,F# 更严格,需要显式转换"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-19
      • 2015-06-26
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多