Do/Will Rust支持函数式编程习惯用法



随着Rust变得越来越丰富,我对它的兴趣开始高涨。我喜欢它支持代数数据类型,尤其是这些类型的匹配,但是对其他的功能性习语有什么想法吗?

  1. 例如,标准库中是否有标准filter/map/reduce函数的集合,更重要的是,您能否以语法上令人愉快的方式将它们链接/组合[1]?

  2. 既然ADT已经有了很好的使用方法,那么单子呢,尤其是一些语法糖呢?

[1] Haskell得到了(.)和(>>),C#扩展方法和可选的LINQ,D具有统一的函数调用语法。

Rust没有HKT,但它的迭代器确实支持以函数风格进行编码,具有更高阶函数(HOF),如mapfilterfold等,并具有方便的链接。

与函数式语言相比,细节有所不同——这些语言通常是垃圾收集的,而Rust程序以确定性的方式处理内存管理,类似于C++RAII——作为程序流的一部分。

为了实现高效的链接,单个HOF返回可组合的懒惰表达式模板,您可以通过使用.to_owned_vec().collect()或其他方法将最终结果转化为数据(一步分配和评估)。

在某些情况下,这是不必要的,返回的表达式模板本身就是迭代器,这可能就足够了。例如,您可以使用for循环对其进行迭代,或者将其作为参数传递给泛型函数。

参见:

  • http://static.rust-lang.org/doc/master/std/iter/index.html

  • http://static.rust-lang.org/doc/master/std/iter/trait.Iterator.html

类似的模式在C++11(带有附加库)和Rust中都是可能的。Rust的泛型不如C++模板强大,但默认情况下的不变性、面向表达式的语法、多态lambda和双向类型推理使它感觉更接近于函数式语言。

关于"扩展方法"和统一调用语法,Rust允许类似的"开放世界"方式来组织代码。您可以将具有更多方法的impl添加到库或程序中任何位置的任何类型,或者通过在其他库上实现自己的trait方法来扩展现有类型。

这使得使用可链接方法调用样式比使用C++更容易(即,不需要修改或派生类型)。

请记住,Haskell的许多习语都与纯粹性有关(例如IO monad、lens.),Rust是多范式的,而不是纯粹的功能性的。为了在程序级别实现引用透明性,您可以使用纯函数,但它的实现通过可变的局部变量而简化。

一种语言必须具有"更高级的kinded类型"才能支持Functors、Applicatives和Monad等概念。换句话说,语言必须能够在*->*的类型上进行抽象,或者在不同类型之间进行函数抽象。Rust目前不支持这种抽象级别。它已经被讨论为未来可能的方向,但我不希望它很快成为焦点。

最新更新