F#函数与C#“Func”tions

时间:2017-02-23 04:35:58

标签: c# f#

所以我遇到了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

所以这对我有意义。它定义了函数是什么,所以如果我将一些数字传递给这个东西,它会对它进行平方并为该结果增加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#tour给我的内容有什么区别?子问题是:IL代码是否有任何不同,即使它是相同的CLR?我会在F#上使用F#的几个原因是什么?

1 个答案:

答案 0 :(得分: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 );

有趣,不是吗? 这称为“类型推断”。同样,F#能够根据使用的方式推断类型的东西。你几乎可以写一个完整的程序,从来没有使用过类型注释。 C#在某种程度上也有这个。这就是我能够调用.Select( i => i+1 )的方式,而C#知道iint,因为.Select之前的任何内容都是IEnumerable<int>。但它非常有限,而不是那么强大。

类型推断只是一个 F#的许多好处。我选择了它,因为你看着它并没有看到它。但还有更多。编译顺序,缺少空值,默认不变,代数数据类型,自动currying和部分应用......事实上,更多的是,不适合SO答案。

那些希望发现奇妙和令人兴奋的函数式编程世界的人,特别是F#,我通常会直接发送到https://fsharpforfunandprofit.com/,进入Wlaschin先生亲切而有能力的人手中。这是一个很好的资源,请阅读所有内容。