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