修改纯函数中的参数

时间:2015-03-26 16:41:49

标签: haskell side-effects

  

我知道我不应该这样做

     

我要求肮脏的黑客做一些讨厌的事情

目标

我希望修改纯函数中的参数。

从而实现通过引用传递的效果。

插图

例如,我有以下功能。

fn :: a -> [a] -> Bool
fn a as = elem a as

我希望修改传入的参数。例如列表as

as' = [1, 2, 3, 4]
pointTo as as'

1 个答案:

答案 0 :(得分:5)

一种常见的误解是,Haskell只是故意阻止你做一些它认为不安全的事情,尽管大多数其他语言允许它。例如,使用C ++'const修饰符就是这种情况:虽然它们是一个有价值的保证,假定保持不变的东西不会被误解,但通常认为整体编译结果不是使用它们时真的会改变;你仍然得到基本上不纯的函数,在堆栈内存帧上实现为一些汇编指令。

已经鲜为人知的是,即使在C ++中,这些const修饰符也允许编译器应用某些优化,这些优化可以在修改引用时完全破坏结果(尽可能使用const_cast - 在Haskell的名字至少会 “不安全”!);只有mutable关键字才能保证隐藏的修改不会弄乱您期望的语义。

在Haskell中,同样的一般问题适用,但更强。 Haskell函数一堆在堆栈帧上运行的汇编指令和从堆栈指向的内存位置。 有时编译器实际上可能生成类似的东西,但一般来说标准非常小心,不建议任何特定的实现细节。实际上,函数可能会被内联,流融合,规则替换等等甚至考虑“修改参数”完全没有意义的事情,因为这些参数可能永远不会存在。 Haskell保证的是,在更高层次的意义上,语义被保留;关于如何考虑函数数学的语义。在数学方面,从概念上讲,谈论“修改过的论点”也毫无意义。