Int & # 8594; int list is not compatible with type int & # 8594; IEnumerable <'a>

Given:

open System.Linq

this is an acceptable expression:

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

However, it 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 # rejects the expression because the function returns int list.

Consider this C # program that does something like this:

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);
        }
    }
}

Iotareturns a List<int>and passing it to is SelectManyacceptable for C #.

Is F #'s design behavior or bug? If this is by design, why does a similar operation work in C #?

+4
source share
2 answers

This is the expected behavior. C # usually does more automatic type conversions than F #:

  • # - List<T>, # IEnumerable<T>, .

  • F # IEnumerable<T>, check - List<T>, IEnumerable<T> ( , ).

F # SelectMany, Seq.collect. F # :

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

#seq<'c> , , seq<'c> ( , # ). :

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

F # int list # List<int>. #, F # ( ). , () seq<int>, , IEnumerable<int>. F # list IEnumerable, F # -: - , . , :

let y = 
    [2; 3; 4].SelectMany(fun n -> [ 1..n ] :> IEnumerable<int>)

F # list IEnumerable<> Seq.ofList:

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

F #: F # System.Collections.Generic.List<> .

+4

Source: https://habr.com/ru/post/1538224/


All Articles