Функции F # vs С# "Func"

Итак, я просмотрел этот тур по F #: https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tour

... и мальчик howdy F # интересный! В самом начале тура определена выборочная функция, которая выглядит довольно просто:

/// You use 'let' to define a function. This one accepts an integer argument and returns an integer. 
/// Parentheses are optional for function arguments, except for when you use an explicit type annotation.
let sampleFunction1 x = x*x + 3

Так что это имеет смысл для меня. Он определяет, что такое функция, если я должен был передать некоторое число в эту вещь, она квадратизирует ее и добавляет 3 к этому результату, как видно из следующей строки в туре:

 /// Apply the function, naming the function return result using 'let'. 
/// The variable type is inferred from the function return type.
let result1 = sampleFunction1 4573

После нескольких минут размышлений я пришел к выводу, что С# тоже может это сделать! Я уверен, действительно люблю С#. Это то, что выше было бы похоже на С#, насколько я могу судить:

        Func<int, int> sampleFunction1 = x => x*x + 3;
        var result = sampleFunction1(4573);

Итак, мой главный вопрос: в чем разница между тем, что я написал на С#, и тем, что показал мне тур F #? Подзапросы: Является ли код IL каким-либо другим, даже если он такой же CLR? Каковы некоторые причины, по которым я буду использовать F # над С#?

Ответ 1

Технически, они эквивалентны. ИЛ может быть немного другим, только потому, что это разные компиляторы, но не так много. По сути, они скомпилированы таким же образом.

Но С# не может этого сделать. Вы заметили, как вам пришлось писать Func<int,int> впереди? Но это очень маленькая игрушечная функция. Что произойдет в более практических случаях? Обратите внимание:

// F#
let f x m = Map.find (x, x+1) m |> Seq.map ((+) 1)

// C#
Func<int, IDictionary<Tuple<int, int>, IEnumerable<int>>, IEnumerable<int>> f = (x, m) => m[Tuple.Create(x, x+1)].Select( i => i+1 );

Забава, не так ли? Это называется "вывод типа". Как и в случае, F # может вывести типы вещей, основываясь на том, как используется материал. Вы можете написать полную программу и никогда не использовать аннотацию типа. В С# это тоже, в некоторой степени. То, как я могу вызвать .Select( i => i+1 ), а С# знает, что i есть int, потому что все, что было до .Select, было IEnumerable<int>. Но он очень ограничен, не так сильно.

Вывод типа является лишь одним из многих преимуществ F #. Я выбрал его, потому что ты смотрел прямо на него и не видел его. Но их гораздо больше. Порядок компиляции, отсутствие нулей, неизменность по умолчанию, типы алгебраических данных, автоматическое каррирование и частичное применение... На самом деле гораздо больше, чем будет соответствовать ответу SO.

Те, кто хочет открыть замечательный и захватывающий мир функционального программирования в целом и F #, в частности, я обычно отправляю в https://fsharpforfunandprofit.com/, в мистера Улашина добрыми и способными руками. Замечательный ресурс, прочитайте все.