c++ - 函数式编程中纯函数的缺点

标签 c++ haskell functional-programming imperative-programming

<分区>

函数式编程中的纯函数是指没有副作用的函数。其含义之一是不能改变输入参数的值。这可以被视为内存利用率的劣势吗?
例如可以说我有一个函数,它只需要一个列表并在其中添加另一个元素。在 C++ 中,它可以像

一样简单

void addElem(std::vector& vec, int a)
{
    vec.insert(a);
}

这个函数显然没有使用比传递的对象已经占用的内存多的内存。
但同样在 Haskell 中也会出现这样的情况。

addElem :: [Int] -> Int -> [Int] 
addElem xs a = xs ++ [a]

现在在这个计算中 xs 没有改变它的值。所以我说的是否正确,在某个时候函数将消耗 xs 的双倍大小的内存,一个用于 xs,另一个用于返回值。或者以某种方式延迟调用确保实际上 xs 仅通过在末尾添加一个元素来返回?
我知道 Monad 是产生可能有副作用的方法。但是 Monad 可以用来简单地修改输入并返回它的值吗?
也可以将 xs++ [a] 更改为 a:xs 消耗更少的内存吗?

最佳答案

纯度意味着该函数不能进行破坏性更新,所以如果

xs ++ [a]

已全面评估,xs 的拷贝必须制作。如果xs,这可能发生在恒定空间中是延迟生成的,不会在其他任何地方引用,因此它可以在创建时被垃圾收集。或者除了 xs 之外还需要一份拷贝- 但是纯度允许两个列表的单元格指向相同的数据,因此不需要复制数据,只需要复制书脊(由最后的 cons 修改)。但如果进行了复制,则旧值 xs仍然可用。

Also can changing xs ++ [a] to a:xs consumes less memory?

是的,可以简单地重复使用 xs , 所需要的只是创建一个新的列表单元格并让它的尾指针指向 xs .

来自评论:

I don't want C++ function to be pure. I want it to change the state of input. And that is what I wanted to be the whole point of the question.

在这种情况下,您需要一个不纯 函数/操作。某些数据结构可以实现,但对于列表,必须重新复制/构建单元格。但是向 std::vector<T> 添加一个元素可能还需要重新分配。

关于c++ - 函数式编程中纯函数的缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13974760/

相关文章:

functional-programming - Erlang 确定记录是否有字段

scala - 将一组对分成两个列表?

haskell - react 香蕉中的行为

loops - 修复与 ArrowLoop

haskell - 难以将 Relation 类型定义为 Category 类的实例

functional-programming - 惰性序列中 "Lose your head"的解释

c++ - 将项目添加到队列

c++ - C2664 无法从 'initializer list' 转换参数

c++ - 如何在win32 windows中创建一个嵌入式文本输入框

c++ - 是否可以将测试标记为在 googletest 运行中花费很长时间