【发布时间】:2017-03-05 07:28:12
【问题描述】:
这是一个关于函数式编程的一般问题,但我也很感兴趣它在特定语言中的答案。
我只是函数式语言的初学者知识,所以请耐心等待。
据我了解,函数式语言侧重于与命令式语言不同的数据结构,因为它们喜欢不变性:持久性数据结构。
例如,它们都有一个不可变的列表概念,您可以在其中从现有列表 l 和两个新项目 x 和 y 中形成一个新列表 x :: l 和 y,而没有 @ 的所有元素987654327@ 需要复制。这很可能是通过新的列表对象在内部指向旧的作为尾部的对象来实现的。
在命令式语言中,很少使用这种数据结构,因为它们提供的引用局部性不如 c 样式数组。
一般来说,寻找支持函数式风格的数据结构是它自己的一项努力,所以如果不必总是这样做,那就太好了。
现在有一个想法,如果有正确的语言支持,如何在函数式编程中使用所有经典数据结构。
一般来说,命令式语言中的数据结构具有在其上定义的修改操作(在伪代码中):
data.modify(someArgument)
函数式的写法是
newData = modified(data, someArgument)
一般的问题是,这通常需要复制数据结构 - 除非语言知道data 实际上不会被其他任何东西使用:然后,可以以变异原始的形式进行修改没有人能分辨出来。
有一大类语言可以推断出“从未在其他地方使用过”的属性:当modified 的第一个参数是一个未绑定的值时,如下例所示:
newData = modified(modified(data, someArgument))
这里,data 可以在其他地方使用,但 modified(data, someArgument) 显然不是。
这在 C++ 中被称为“右值”,而在 C++ 的最新版本中,具有讽刺意味的是,它根本没有功能,否则可能会重载此类右值。
例如,可以这样写:
Data modified(Data const& data) { // returns a modified copy }
Data modified(Data && data) { // returns the modified original }
这意味着在 C++ 中,实际上可以采用任何可变的高效数据结构并将其转换为具有可以以纯函数方式使用的不可变 api,就像命令式版本一样有效。 em>
(有一点需要注意的是,在 C++ 中,有时强制强制右值重载仍然需要强制转换。当然,在实现此类数据结构时需要小心,即在使用右值重载时。虽然这可能会有所改进.)
现在我的问题:
实际的函数式语言是否有类似的机制?还是因为其他原因不需要这样做?
(我标记了一些我特别感兴趣的特定语言。)
【问题讨论】:
-
@duplode 你并没有真正阅读这个问题,是吗?
-
你是对的,确实:它不是重复的,我撤回了我的近距离投票。不过,没有必要对问题进行被动积极的编辑——只需要清楚地指出错误(在这种情况下,是我的错误)。在任何情况下:(1)如果您想了解更多关于“[您提到的技巧]出于其他原因不需要”的原因,您可能会发现我链接到的问题中的参考很有用。 (2) 目前有三个“过于宽泛”的近距离投票,我认为这也不合适(也许更具体的标题有助于避免进一步的误解)。
-
@duplode 标题很好的建议。
-
您声称“这意味着在 C++ 中,实际上可以采用任何可变的高效数据结构并将其转换为具有可以以纯函数方式使用的不可变 api,就像命令式一样有效如果您需要持久性,版本将是“显然是错误的。你到底想说什么?
标签: scala haskell f# functional-programming