【发布时间】:2019-12-23 20:53:24
【问题描述】:
这个 C 代码在概念上可以描述为创建一个与输入数组相同但第一个元素为 1 的新数组:
int* retire_and_update(int* arr) {
arr[0] = 1;
return arr;
}
这是一个纯函数(wink wink nudge nudge),只要不进一步引用输入数组及其元素。 C 类型系统不会为我们强制执行,但原则上似乎可以强制执行。
gcc生成的代码简单高效:
retire_and_update:
movq %rdi, %rax
movl $1, (%rdi)
ret
我们的函数通过在恒定时间内创建一个全新的数组并且不使用额外的内存来实现看似不可能的事情。好的。可以编写一个具有类似数组输入和输出的 Haskell 函数,并且可以用类似的代码有效地实现吗?有没有办法表达“这是对这个变量的最后引用”,以便纯函数可以在幕后蚕食变量?
如果函数被内联,那么这里不需要发生任何有趣的事情,所以假设调用者和函数将分别编译。
【问题讨论】:
-
IIUC“唯一性类型”或类似的线性类型,这样做。不幸的是,这些不是 Haskell 类型系统的特性。 Haskell 中的常规方法是使用the
STmonad 在概念上纯设置中实现突变(暂时进入具有可变状态的monad,但类型系统保证计算是确定性的并且状态不会泄漏)。不过,这与您所说的完全不同。 -
Clean 是一种使用唯一性类型的函数式语言,也受到 Haskell 的影响。
-
related:一个纯
UArray Int Bool正在循环中更新,没有任何对其先前值的引用。与您在此处表达的类似,它可以就地更新,但似乎不是。
标签: c haskell ghc in-place purely-functional