【问题标题】:Does/Will Rust support functional programming idioms?Rust 是否/将支持函数式编程习惯用法?
【发布时间】:2013-08-22 07:52:10
【问题描述】:

随着 Rust 越来越充实,我对它的兴趣开始激起。 我喜欢它支持代数数据类型,特别是那些匹配的事实, 但是对其他功能性习语有什么想法吗?

  1. 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能否以合乎语法的方式链接/组合它们[1]?

  2. 既然已经有一些优雅的方式可以使用 ADT,那么 monad 怎么样,尤其是一些语法糖呢?

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

【问题讨论】:

  • 看看这个可以派生HKT的宏:gist.github.com/14427/af90a21b917d2892eace
  • 这令人印象深刻!尽管类型变量的命名似乎相当随意。我什至不知道你可以拥有带有类型变量的特征。这是一个很好的 hack。

标签: functional-programming rust


【解决方案1】:

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

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

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

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

见:

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

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

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

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

【讨论】:

  • 这是信息丰富的补充其他答案。但是,与 D 相比,使用特征不意味着您引入了运行时多态性和潜在的不可内联性吗?我看到你可以使用表达式模板来避免它(整洁!),但如果我可以对相同的代码使用特征,那就更棒了......无论如何,它仍然优于 C# 的 IEnumerable。
  • traits 用于运行时和编译时多态性;它们就像提议的 C++ 概念(限制模板参数以获得更好的编译时错误),或者您可以实例化一个“特征对象”,在这种情况下,该特征用于格式化一个 vtable。与 C++ 一样,只有在明确要求时才能获得 vtable。
  • 与 C++ 不同,(和 Go 一样)vtables ptrs 带有一个指针;底层结构不包含任何类信息。
  • 与 C++ 不同,需要一些特征和方法的组合来启用编译时多态性(您只能基于接收者“重载”),即使最终结果与 C++ 重载相同。这是 rust 团队的一个设计选择,关于如何组织/呈现多态性。而不是一个低级的问题。它旨在使模板错误不那么可怕。
  • 他们能够使用 .unwrap_or() 链接从“选项”中提取值的条件,或者对值进行迭代(如果存在)......所以你当然可以在这些值的地方编写优雅的表达式被传递。
【解决方案2】:

一种语言必须具有“更高种类的类型”才能支持 Functors、Applicatives 和 Monads 等概念。换句话说,语言必须能够抽象出 * -> * 的类型,或者从一个类型到另一个类型的函数。 Rust 当前不支持这种抽象级别。 discussed 一直是未来可能的方向,但我不希望它很快成为焦点。

【讨论】:

  • C# 通过 LINQ 支持 Monad。 IEnumerable 和 IObservable 都是 monadic / linqable。但是 C# 不支持更高种类的类型,所以我不确定这个答案中的断言是否正确。或许您的意思更具体一些。
猜你喜欢
  • 2018-05-12
  • 2013-08-31
  • 2011-04-07
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多