所以我遇到了这个F#之旅:https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tour
...和男孩你好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
Run Code Online (Sandbox Code Playgroud)
所以这对我来说很有意义.它定义了函数是什么,所以如果我将一些数字传递给这个东西,它会对它进行平方并为该结果增加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
Run Code Online (Sandbox Code Playgroud)
经过几分钟的思考后,我得出结论,C#也可以做到这一点!我确实非常喜欢C#.就我所知,这就是上面在C#中的样子:
Func<int, int> sampleFunction1 = x => x*x + 3;
var result = sampleFunction1(4573);
Run Code Online (Sandbox Code Playgroud)
所以我的主要问题是,我在C#中写的内容与F#tour给我的内容有什么区别?子问题是:IL代码是否有任何不同,即使它是相同的CLR?我会使用F#而不是C#的几个原因是什么?
Fyo*_*kin 28
从技术上讲,这些是等价的.IL可能有点不同,只是因为这些是不同的编译器,但并不多.实质上,这些是以相同的方式编译的.
但是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 );
Run Code Online (Sandbox Code Playgroud)
好玩,不是吗?
这称为"类型推断".如同,F#能够根据使用的东西推断出类型的东西.你几乎可以写一个完整的程序,从来没有使用过类型注释.C#在某种程度上也有这个.这就是我能够调用的方式.Select( i => i+1 ),而C#知道这i是int,因为之前.Select发生的事情是IEnumerable<int>.但它非常有限,而不是那么强大.
类型推断仅仅是一个的F#的诸多好处.我选择了它,因为你看着它并没有看到它.但还有更多.编译顺序,缺少空值,默认不变性,代数数据类型,自动currying和部分应用......实际上,还要比SO答案更合适.
那些希望发现精彩和令人兴奋的函数式编程世界的人,特别是F#,我通常会直接发送到https://fsharpforfunandprofit.com/,进入Wlaschin先生亲切而有能力的人手中.一个美妙的资源,阅读所有.