我知道我不应该这样做
我要求肮脏的黑客做一些讨厌的事情
我希望修改纯函数中的参数。
从而实现通过引用传递的效果。
例如,我有以下功能。
fn :: a -> [a] -> Bool
fn a as = elem a as
我希望修改传入的参数。例如列表as
。
as' = [1, 2, 3, 4]
pointTo as as'
答案 0 :(得分:5)
一种常见的误解是,Haskell只是故意阻止你做一些它认为不安全的事情,尽管大多数其他语言允许它。例如,使用C ++'const
修饰符就是这种情况:虽然它们是一个有价值的保证,假定保持不变的东西不会被误解,但通常认为整体编译结果不是使用它们时真的会改变;你仍然得到基本上不纯的函数,在堆栈内存帧上实现为一些汇编指令。
已经鲜为人知的是,即使在C ++中,这些const
修饰符也允许编译器应用某些优化,这些优化可以在修改引用时完全破坏结果(尽可能使用const_cast
- 在Haskell的名字至少会 “不安全”!);只有mutable
关键字才能保证隐藏的修改不会弄乱您期望的语义。
在Haskell中,同样的一般问题适用,但更强。 Haskell函数不一堆在堆栈帧上运行的汇编指令和从堆栈指向的内存位置。 有时编译器实际上可能生成类似的东西,但一般来说标准非常小心,不建议任何特定的实现细节。实际上,函数可能会被内联,流融合,规则替换等等甚至考虑“修改参数”完全没有意义的事情,因为这些参数可能永远不会存在。 Haskell保证的是,在更高层次的意义上,语义被保留;关于如何考虑函数数学的语义。在数学方面,从概念上讲,谈论“修改过的论点”也毫无意义。