修改纯函数中的参数
Modify an argument in a pure function
I am aware that I should not do this
I am asking for dirty hacks to do something nasty
目标
我想修改纯函数中的参数。
从而实现引用传递的效果
插图
比如我得到了下面的函数
fn :: a -> [a] -> Bool
fn a as = elem a as
我想修改传入的参数。例如列表as
。
as' = [1, 2, 3, 4]
pointTo as as'
这是一个常见的误解,认为 Haskell 只是故意阻止您做它认为不安全的事情,尽管大多数其他语言都允许这样做。例如,使用 C++ 的 const
修饰符就是这种情况:虽然它们是一个有价值的保证,即应该保持不变的东西不会被错误搞乱,但通常假设整体编译结果不会使用它们时真正改变;你仍然得到基本上不纯的函数,在堆栈内存帧上实现为一些汇编指令。
鲜为人知的是,即使在 C++ 中,这些 const
修饰符也允许编译器应用某些优化,这些优化可以在修改引用时完全破坏结果(可能使用 const_cast
–在 Haskell 中,它的名称中至少 “不安全”!);只有 mutable
关键字可以保证隐藏的修改不会破坏您期望的语义。
在 Haskell 中,同样的普遍问题也适用,但更强烈。 Haskell 函数是 而不是 一堆在堆栈帧和从堆栈指向的内存位置上运行的汇编程序指令。 有时 编译器实际上可能会生成类似的东西,但通常标准非常小心,不会建议任何特定的实现细节。所以实际上,函数可能会被内联、流融合、规则替换等,甚至在考虑“修改参数”时完全没有意义,因为也许参数根本不存在。 Haskell 保证的是,在更高层次的意义上,语义 被保留;您如何从数学上 考虑函数的语义。在数学中,从概念上讲,谈论“修正论证”也毫无意义。
I am aware that I should not do this
I am asking for dirty hacks to do something nasty
目标
我想修改纯函数中的参数。
从而实现引用传递的效果
插图
比如我得到了下面的函数
fn :: a -> [a] -> Bool
fn a as = elem a as
我想修改传入的参数。例如列表as
。
as' = [1, 2, 3, 4]
pointTo as as'
这是一个常见的误解,认为 Haskell 只是故意阻止您做它认为不安全的事情,尽管大多数其他语言都允许这样做。例如,使用 C++ 的 const
修饰符就是这种情况:虽然它们是一个有价值的保证,即应该保持不变的东西不会被错误搞乱,但通常假设整体编译结果不会使用它们时真正改变;你仍然得到基本上不纯的函数,在堆栈内存帧上实现为一些汇编指令。
鲜为人知的是,即使在 C++ 中,这些 const
修饰符也允许编译器应用某些优化,这些优化可以在修改引用时完全破坏结果(可能使用 const_cast
–在 Haskell 中,它的名称中至少 “不安全”!);只有 mutable
关键字可以保证隐藏的修改不会破坏您期望的语义。
在 Haskell 中,同样的普遍问题也适用,但更强烈。 Haskell 函数是 而不是 一堆在堆栈帧和从堆栈指向的内存位置上运行的汇编程序指令。 有时 编译器实际上可能会生成类似的东西,但通常标准非常小心,不会建议任何特定的实现细节。所以实际上,函数可能会被内联、流融合、规则替换等,甚至在考虑“修改参数”时完全没有意义,因为也许参数根本不存在。 Haskell 保证的是,在更高层次的意义上,语义 被保留;您如何从数学上 考虑函数的语义。在数学中,从概念上讲,谈论“修正论证”也毫无意义。