INT - > INT表不与int类型兼容 - > IEnumerable的<“A> [英] int -> int list is not compatible with type int -> IEnumerable<'a>

查看:153
本文介绍了INT - > INT表不与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 to IEnumerable<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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆