任何人都可以解释编程语言中的不变量是什么以及它们为何重要?
答案 0 :(得分:4)
不变量是您希望始终保持的数据属性。不变量非常重要,因为它们允许您将业务逻辑与验证分开 - 您的函数可以安全地假设它们没有收到无效数据。
例如,在国际象棋游戏中,你有一个不变量,即每次只有一件可能占据棋盘上的给定方格。不变量可以在编译时强制执行,通常通过使用静态类型系统来通过构造使对象正确,例如通过将板表示为可选块的矩阵。它们也可以在运行时强制执行,例如,在尝试进行无效移动时引发异常。
函数式编程语言中的方法通常是使对象不可变,并防止构造无效状态。在OOP语言中,对象通常是可变的,期望方法防止无效状态转换。
无论哪种方式,强制执行不变量都可确保您的程序始终处于可预测状态,这样可以更轻松地推理代码并安全地进行更改,而不会引入回归。
答案 1 :(得分:4)
任何字段中的不变量 - 是允许您区分"对象"的值(通常是数字)。如果那些不变量不一样。
例如,如果你有一个数学术语说
(x+3)²+1
并且您希望将一个不变量替换为x
的替代随机数,我的rng选择了x=0
- 所以不变量将是
(0+3)²+1 = 9+1 = 10
然后如果我错误地改变了术语
x²+6x+3 + 1 = x² + 6x +4
再次使用x = 0
进行测试我看到0²+0+4 = 4
与10
不同,因此我知道必须有错误。
但另一方面,如果我将这个词改为
x²+3x+9 +1 = x²+3x+10
x=0
的不变量将再次为10
- 所以我们看到了
equational reasoning
为什么这会在(功能)编程中变得有趣 - 你将在这个上下文中听到的一个表达式是equational reasoning
,这意味着如果你可以将算法/函数/术语转换为另一个没有失去平等。对于像haskell这样的语言,通过限制不变性,没有副作用等,这通常是正确的。而在oo中,这通常是不正确的。均衡推理可以缩小错误发生的区域,因此调试/查找错误相对容易。
property based testing
不变量常见的另一个字段是基于属性的测试:这里reverse :: [a] -> [a]
的标准示例,即(链接)列表上的反向函数,具有reverse . reverse == id
的属性,即反转两次是就像无所事事一样。
如果你把它放在Quickcheck测试中 - 测试生成器生成任意列表并检查这个属性 - 如果其中一个(可能)数千个测试失败你知道,在哪里改进你的代码。
Compiler optimizations
某些属性也可用于优化代码,例如,对于所有函数fmap f . fmap g == fmap (f . g)
并且左侧遍历数据结构两次,其中右侧只进行一次遍历,编译器可以替换他们让你的代码快两倍。