c# - F# 函数与 C# "Func"的对比

标签 c# f#

所以我遇到了 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# 知道 iint ,因为无论.Select 之前是什么是IEnumerable<int> .但它非常有限,远没有那么强大。

类型推断只是 F# 众多优势中的一个。我选择了它,因为你正看着它而没有看到它。但还有更多。编译顺序、空值缺失、默认不变性、代数数据类型、自动柯里化(Currying)和部分应用……事实上,比 SO 答案要多得多。

那些希望发现一般函数式编程,特别是 F# 的精彩和令人兴奋的世界的人,我通常会立即发送到 https://fsharpforfunandprofit.com/ ,交到Wlaschin先生善良能干的手中。一个很棒的资源,全部阅读。

关于c# - F# 函数与 C# "Func"的对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42407150/

相关文章:

c# - 单击按钮后如何在标签中显示文本

serialization - F#:记录查询字符串

xml - F# XML 类型提供程序公共(public)元素

.net - 为什么需要在 F# 异步工作流中使用 "do! Async"样式函数?

c# - .NET System.IO.BinaryWriter 写入的原始字节是否可由其他平台读取?

c# - Web服务的自动化测试框架

c# - ASP.NET 应用程序中搜索结果的缓存体系结构

f# - 无点函数中的异常处理

c# - 如何制作一个在主线程中触发事件的 C# 计时器?

c# - 如何设计一个日历控件