2017-02-23 23 views
15

против Так что я натыкался на этот тур по F #: https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tourF # функции C# ных "Func"

... и мальчик здор`ово это 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 

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

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

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

+2

IL, вероятно, будет отличаться только потому, что компиляторы работают с совершенно разными языками и, следовательно, имеют разные оптимизации, интерпретации, переводы и т. Д. Вам нужно найти кого-то, знакомого с обоими языками, чтобы точно рассказать вам, но с помощью инструмента дизассемблера IL (например, [ILSpy] (http://ilspy.net/)) вы можете легко открыть исполняемые файлы/библиотеки DLL и самостоятельно изучить. – Abion47

+1

Вы не заметите большой разницы в функциях одной линейки. На самом деле многие вызовы .NET BCL будут одинаково выглядеть как на C#, так и на F #. Однако, если вы создадите что-то более сложное, вы увидите преимущества F #, как с точки зрения синтаксиса, так и структуры.Особенно, если вы хотите отойти от парадигмы OO и уменьшить изменяемые (движущиеся) части в вашем проекте. – s952163

ответ

27

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

Но C# не может сделать точно это. Вы заметили, как вам пришлось писать 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 # может вывести типы материалов, основанные на использовании материалов. Вы можете написать полную программу и никогда не использовать аннотацию типа. В C# это тоже, в некоторой степени. Вот как я могу позвонить .Select(i => i+1), а C# знает, что i - int, потому что независимо от того, что было до .Select, было IEnumerable<int>. Но это очень ограниченно, не так сильно.

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

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

+2

Я отметил неизменность в туре, и мне это понравилось совсем немного! Мне также нравится ваш пример, как ужасно выглядит func на C#. Есть ли у вас представление о том, как это может измениться с новым материалом Tuple в C# 7? –

+4

Не так много. Это сделает нотацию типа немного короче, но вам все равно придется написать ее. Вещь с C# - независимо от того, сколько блестящих функций она получает, вы не можете исправить некоторые фундаментальные проблемы (например, nulls, изменчивость), не нарушая старый код. И если вы нарушаете старый код, то это новый язык, и в этом случае вы можете просто переместиться на F #. –

+3

Я думаю, что частичное приложение заслуживает чуть большего освещения в ответе. Это чисто случайный случай, когда OP использовал 'let sampleFunction1 x = ...' вместо того, чтобы 'let sampleFunction1 xy = ...' в качестве примера и что C#, эквивалентный последнему, будет 'Func >' а не 'Func ' определенно .. примечателен, мягко говоря. – ildjarn