Rust是否支持函数式编程习惯用法?

28
我喜欢Rust支持代数数据类型和特别是匹配它们的功能,但是有没有计划支持其他函数式编程习惯呢?
例如,标准库中是否有一组标准的filter/map/reduce函数,并且更重要的是,你能否以一种令人愉悦的语法方式链式/组合它们呢?
既然已经有了优雅的ADT使用方法,那么怎么样关于monads呢?特别是一些对它们的语法糖?
[1] Haskell有(.)和(>>>),C#有扩展方法和可选的LINQ,D语言有统一的函数调用语法。

1
看看这个可以推导HKT的宏:https://gist.github.com/14427/af90a21b917d2892eace - CMCDragonkai
太厉害了!虽然类型变量的命名似乎相当随意。我甚至不知道你可以使用带有类型变量的特征。这是一个绝妙的技巧。 - Sebastian Graf
2个回答

26
Rust没有高阶类型(HKT),但其迭代器支持使用高阶函数(HOF)编写函数式风格的代码,例如map, filter, fold等,并且能够方便地进行链接。
与函数式语言不同,具体细节也有所区别。通常情况下,函数式语言是具有垃圾回收机制的,而 Rust 程序以确定性的方式处理内存管理,类似于 C++ RAII,作为程序流的一部分。
为了实现有效的链接,个别 HOF 返回可组合的惰性表达式模板,你可以通过添加 .to_owned_vec().collect() 等方法来将最终结果转换为数据(在一步中分配和计算)。在某些情况下,这并不是必要的,返回的表达式模板本身就是一个迭代器,可能已经足够使用。例如,你可以使用 for 循环遍历它,或将其作为参数传递给通用函数。
参考: 类似的模式在 C++11(使用附加库)和 Rust 中都可以实现。Rust 的泛型不如 C++ 模板强大,但默认的不可变性,面向表达式的语法,多态 lambda 和双向类型推断使得它更接近函数式语言。
关于“扩展方法”和统一调用语法,Rust 允许类似的“开放式”代码组织方式。你可以在库或程序的任何位置添加具有更多方法的 impl,也可以通过自己实现 trait 上的方法来扩展其他库中已存在的类型。这使得使用可链接的方法调用风格比C++更容易(即少需修改或派生类型)。
请记住,Haskell的许多习语都与纯度有关(例如IO monad、lenses等),而Rust是多范式而不是纯函数式的。您可以拥有一个纯函数以获得程序级别的参考透明度的好处,但其实现可以通过可变本地变量简化。

1
这很有信息量,并且补充了其他答案。但是使用traits并不意味着你引入了运行时多态性和潜在的无法内联代码的问题,与D语言相比如何?我看到你可以通过表达式模板避免这个问题(很棒!),但如果我能为相同的代码使用traits,那就更棒了...无论如何,它仍然优于C#的IEnumerable。 - Sebastian Graf
2
特质(traits)用于运行时和编译时多态性;它们类似于提议的 C++ 概念(用于更好的编译时错误的限定模板参数),或者您可以实例化一个“特质对象”,在这种情况下,特质用于格式化虚函数表。与 C++ 一样,只有在显式请求时才会获得虚函数表。 - centaurian_slug
1
与C++不同,为了实现编译时多态性(你只能基于接收器进行“重载”),需要一些特征和方法的组合,即使最终结果与C++重载相同。这是Rust团队在多态性组织/呈现方面的设计选择,而不是低级问题。它旨在使模板错误更少令人恐惧。 - centaurian_slug
关于您最后编辑的单子问题:我不仅发现它们对IO操作很有用,而且对优雅地处理Maybe、Either等也很有帮助。当然,这对我来说是新潮流。 - Sebastian Graf
1
他们有能力使用.unwrap_or()链接对'option'中的条件值进行提取,或者迭代该值(如果存在)...因此您可以编写优雅的表达式,其中这些值被传递。 - centaurian_slug
显示剩余3条评论

16

一种编程语言必须具有“高阶类型”才能支持像函子、应用函子和单子这样的概念。换句话说,该语言必须能够对 * -> * 类型或从类型到类型的函数进行抽象。Rust目前不支持这种抽象层次。虽然已经讨论作为可能的未来方向,但我不认为它会很快成为焦点。


嗯,https://dev59.com/YWQn5IYBdhLWcg3wJ0YO - Sebastian Graf
2
C#通过LINQ支持单子(Monads)。IEnumerable<T>和IObservable<T>都是单子/可LINQ化的。然而,C#不支持更高级别的类型,因此我不确定这个答案中的断言是否正确。也许你的意思是稍微具体一些的东西。 - bradgonesurfing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接