我喜欢 Rust 支持代数数据类型,特别是这些数据类型的匹配, 但是有计划支持其他函数式习语吗?
例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能否以语法上令人愉悦的方式链接/组合它们[1]?
既然已经有了使用 ADT 的优雅方法,那么 monad 怎么样,特别是它们的一些语法糖呢?
[1] Haskell 拥有 (.) 和 (>>>)、C# 扩展方法和可选的 LINQ,D 具有统一的函数调用语法。
Rust 没有 HKT,但它的迭代器 do 支持使用高阶函数 (HOF) 进行函数式编码,例如
map
、filter
、fold
等,并且具有方便的链接。
与函数式语言相比,细节有所不同 - 这些语言通常被垃圾收集,而 Rust 程序以确定性方式处理内存管理,类似于 C++ RAII - 作为程序流程的一部分。
为了实现高效的链接,各个 HOF 返回可组合的惰性表达式模板,并且您可以通过使用
.to_owned_vec()
或 .collect()
或其他方式完成,将最终结果转换为数据(一步分配和评估)。
在某些情况下,这不是必需的,返回的表达式模板本身就是一个迭代器,这可能就足够了。例如,您可以使用
for
循环对其进行迭代,或将其作为参数传递给通用函数。
参见:
C++11(带有附加库)和 Rust 中都可能存在类似的模式。 Rust 的泛型不如 C++ 模板那么强大,但默认的不变性、面向表达式的语法、多态 lambda 和双向类型推断让它感觉稍微更接近于函数式语言。
关于“扩展方法”和统一调用语法,Rust 允许采用类似的“开放世界”方式组织代码。您可以将具有更多方法的
impl
添加到库或程序中任何位置的任何类型,或者通过在其他库上实现您自己的特征方法来扩展其他库中的现有类型。
这使得使用可链接方法调用风格比在 C++ 中更容易(即更少需要修改或派生类型)。
请记住,Haskell 的许多惯用语都与纯度有关(例如 IO monad、lens..),而 Rust 是多范式的,而不是纯函数的。您可以使用纯函数来获得程序级别引用透明性的好处,并且通过可变局部变量简化了其实现。
语言必须具有“更高种类的类型”来支持函子、应用程序和单子等概念。换句话说,语言必须能够抽象 * -> * 的类型,或者从类型到类型的函数。 Rust 目前不支持这种抽象级别。它已被讨论作为未来可能的方向,但我不认为它会很快成为焦点。