gpt4 book ai didi

c# - int -> int 列表与类型 int -> IEnumerable<'a> 不兼容

转载 作者:太空狗 更新时间:2023-10-30 00:07:32 25 4
gpt4 key购买 nike

给定:

open System.Linq

这是一个可接受的表达方式:

[2; 3; 4].SelectMany(fun n -> { 1..n })

然而这不是:

[2; 3; 4].SelectMany(fun n -> [ 1..n ])

错误信息是这样的:

    int -> int list    
is not compatible with type
int -> System.Collections.Generic.IEnumerable<'a>

F# 正在拒绝该表达式,因为该函数正在返回 int list .

考虑这个执行类似操作的 C# 程序:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SelectManyCs
{
class Program
{
static List<int> Iota(int n)
{
var ls = new List<int>();

for (var i = 0; i < n; i++) ls.Add(i);

return ls;
}

static void Main(string[] args)
{
var seq = new List<int>() { 2, 3, 4 };

foreach (var elt in seq.SelectMany(Iota))
Console.WriteLine(elt);
}
}
}

Iota返回 List<int>并将其传递给 SelectMany C# 可以接受。

F# 行为是设计使然还是错误?如果是设计使然,为什么类似的操作在 C# 中有效?

最佳答案

这是预期的行为。 C# 通常比 F# 做更多类型间的自动转换:

  • 在 C# 中,lambda 函数的结果是 List<T> , 但 C# 编译器会自动将结果转换为 IEnumerable<T> ,这是函数的预期返回类型。

  • 在 F# 中,编译器不会自动将结果转换为 IEnumerable<T>所以你的第二个片段没有输入检查 - 因为它正在返回 list<T>这与预期的类型不同 IEnumerable<T> (您可以将列表转换为可枚举的,但它们是不同的类型)。

F# 库定义了自己的 SelectMany 版本操作称为 Seq.collect . F# 函数具有以下类型:

> Seq.collect;;
val it : (('a -> #seq<'c>) -> seq<'a> -> seq<'c>)

在这里,输入 #seq<'c>明确表示结果可以是任何可以转换为 seq<'c> 的类型(这就是名称中的 # 的意思)。这就是为什么 answer to your previous question作品:

[2; 3; 4] |> Seq.collect (fun n -> [ 1..n ])

关于c# - int -> int 列表与类型 int -> IEnumerable<'a> 不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23316324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com