INT - &GT; INT表不与int类型兼容 - &GT; IEnumerable的&LT;“A&GT; [英] int -> int list is not compatible with type int -> IEnumerable<'a>
问题描述
由于:
open System.Linq
这是一个可以接受的EX pression:
this is an acceptable expression:
[2; 3; 4].SelectMany(fun n -> { 1..n })
然而,这并不:
however this is not:
[2; 3; 4].SelectMany(fun n -> [ 1..n ])
该错误消息说:
The error message says:
int -> int list
is not compatible with type
int -> System.Collections.Generic.IEnumerable<'a>
F#被拒绝EX pression因为该函数返回一个 INT列表
。
考虑一下这个C#程序,它有类似的:
Consider this C# program which does something similar:
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);
}
}
}
丝毫
返回名单,其中,INT&GT;
并将它传递给的SelectMany
是可以接受的C#。
Iota
returns a List<int>
and passing it to SelectMany
is acceptable to C#.
是由设计F#的行为,或者是错误吗?如果是在设计上,为什么同样的操作工作在C#?
Is the F# behaviour by design or is it bug? If it's by design, why does the similar operation work in C#?
推荐答案
这是一个预期的行为。 C#一般不超过类型F#之间有更多的自动转换:
This is an expected behavior. C# generally does more automatic conversions between types than F#:
-
在C#中,lambda函数的结果是
名单,其中,T&GT;
,但C#编译器自动将结果的IEnumerable&LT转换; T&GT;
,这是函数的预期收益类型
In C#, the result of the lambda function is
List<T>
, but the C# compiler automatically converts the result toIEnumerable<T>
, which is the expected return type of the function.
在F#中,编译器不会自动把结果转换的IEnumerable&LT; T&GT;
等你的第二个片段没有类型检查 - 因为它返回列表&LT; T&GT;
这是一个不同类型的比预期的的IEnumerable&LT; T&GT;
(你可以投列表枚举,但它们是不同类型)。
In F#, the compiler does not automatically cast the result to IEnumerable<T>
and so your second snippet does not type check - because it is returning list<T>
which is a different type than the expected IEnumerable<T>
(you can cast list to enumerable, but they are different types).
在F#库定义它自己版本的的SelectMany
操作称为 Seq.collect
。 F#的功能有以下类型:
The F# library defines its own version of the SelectMany
operation called Seq.collect
. The F# function has the following type:
> Seq.collect;;
val it : (('a -> #seq<'c>) -> seq<'a> -> seq<'c>)
在这里,键入#序列&LT;'C&GT;
明确地说,结果可以是任何类型,可转换为以次&LT; C&GT;
(这是什么#
的名字的意思)。这就是为什么<一href="http://stackoverflow.com/questions/23315615/calling-ienumerable-selectmany/23315699#23315699">answer您的previous问题作品:
Here, the type #seq<'c>
explicitly says that the result can be of any type that can be converted to seq<'c>
(this is what the #
in the name means). This is why the answer to your previous question works:
[2; 3; 4] |> Seq.collect (fun n -> [ 1..n ])
这篇关于INT - &GT; INT表不与int类型兼容 - &GT; IEnumerable的&LT;“A&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!