所以我遇到了 F# 之旅:https://learn.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# 之旅向我展示的内容有什么区别?子问题是:即使是相同的 CLR,IL 代码是否有任何不同?我会使用 F# 而不是 C# 的几个原因是什么?
最佳答案
从技术上讲,它们是等价的。 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# 知道 i
是int
,因为无论.Select
之前是什么是IEnumerable<int>
.但它非常有限,远没有那么强大。
类型推断只是 F# 众多优势中的一个。我选择了它,因为你正看着它而没有看到它。但还有更多。编译顺序、空值缺失、默认不变性、代数数据类型、自动柯里化(Currying)和部分应用……事实上,比 SO 答案要多得多。
那些希望发现一般函数式编程,特别是 F# 的精彩和令人兴奋的世界的人,我通常会立即发送到 https://fsharpforfunandprofit.com/ ,交到Wlaschin先生善良能干的手中。一个很棒的资源,全部阅读。
关于c# - F# 函数与 C# "Func"的对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42407150/