Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 这个术语是什么;理由是;你是说计算机科学?_Scala_Haskell_Functional Programming - Fatal编程技术网

Scala 这个术语是什么;理由是;你是说计算机科学?

Scala 这个术语是什么;理由是;你是说计算机科学?,scala,haskell,functional-programming,Scala,Haskell,Functional Programming,在学习函数式编程的过程中,我经常遇到“reasonabout”这个术语,尤其是在纯函数和/或引用透明的上下文中。有人能解释一下这到底意味着什么吗?通常在编写程序时,您的工作不仅仅是编写代码,还需要了解代码显示的一些属性。你可以通过两种方法得出这些性质:逻辑分析或经验观察 此类财产的例子包括: 正确性(程序是否执行了它应该执行的操作) 性能(需要多长时间) 可伸缩性(输入如何影响性能) 安全性(算法可能被恶意滥用) 当你根据经验测量这些属性时,你得到的结果精度有限。因此,从数学上证明这些性质要

在学习函数式编程的过程中,我经常遇到“reasonabout”这个术语,尤其是在纯函数和/或引用透明的上下文中。有人能解释一下这到底意味着什么吗?

通常在编写程序时,您的工作不仅仅是编写代码,还需要了解代码显示的一些属性。你可以通过两种方法得出这些性质:逻辑分析或经验观察

此类财产的例子包括:

  • 正确性(程序是否执行了它应该执行的操作)
  • 性能(需要多长时间)
  • 可伸缩性(输入如何影响性能)
  • 安全性(算法可能被恶意滥用)
当你根据经验测量这些属性时,你得到的结果精度有限。因此,从数学上证明这些性质要优越得多,但这并不总是容易做到的。函数式语言的设计目标之一是使其属性的数学证明更易于处理。这就是对程序进行推理的典型含义


就函数或更小的单元而言,上述内容适用,但有时作者也只是指思考算法或设计算法。这取决于具体用途


顺便提一下,我们可以举出一些例子,说明如何对这些事情进行推理,以及如何进行经验观察:

正确性:我们可以证明代码是正确的,如果我们能平等地证明它做了它应该做的事情。所以对于排序函数,如果我们能证明我们给它的任何列表都具有被排序的属性,我们知道我们的代码是正确的。根据经验,我们可以创建一个单元测试套件,在这里我们给出输入的代码示例,并检查代码是否具有所需的输出

性能和可伸缩性:我们可以分析我们的代码并证明算法的性能界限,这样我们就知道它所花费的时间如何依赖于输入的大小。根据经验,我们可以对代码进行基准测试,并查看它在特定机器上实际运行的速度。我们可以进行负载测试,看看我们的机器/算法在折叠/变得不切实际之前可以接受多少实际输入。

关于代码的推理,在最宽松的意义上,意味着思考您的代码及其真正的功能(而不是您认为它应该做什么)

  • 意识到当您向代码抛出数据时代码的行为方式
  • 知道哪些东西可以在不破坏它的情况下进行重构,以及
  • 密切关注可以执行哪些优化
除其他外。对我来说,在调试或重构时,推理部分起着最大的作用

举一个你提到的例子:当我试图找出函数的错误时,引用透明性对我帮助很大。引用透明性保证了当我拨弄函数时,给它不同的参数,我知道函数在我的程序中的反应是相同的。它只依赖于它的参数。这使得函数更容易推理,而不是命令式语言,在命令式语言中,函数可能依赖于某些外部变量,这些变量在我的眼皮底下可能会发生变化

另一种看待它的方式(这在重构时更有用)是,您越知道代码满足某些属性,就越容易推理。例如,我知道

map f (map g xs) === map (f . g) xs
这是一个有用的属性,我可以在重构时直接应用它。事实上,我可以声明Haskell代码的这些属性,这使我们更容易进行推理。我可以尝试在Python程序中声明这个属性,但我对它的信心要小得多,因为如果我在选择
f
g
时运气不好,结果可能会大不相同。

通常当人们说“推理”时,他们指的是“等式推理”,这意味着在不运行代码的情况下验证代码的属性

这些属性可能非常简单。例如,给定
()
id
的以下定义:

id :: a -> a
id x = x

(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) = \x -> f (g x)
。。。然后,我们可能想证明:

f . id = f
这很容易证明,因为:

(f . id) = \x -> f (id x) = \x -> f x = f
请注意我是如何为所有
f
证明这一点的。这意味着我知道这个属性无论如何都是真的,因此我不再需要在某种单元测试套件中测试这个属性,因为我知道它永远不会失败。

非正式地说,它意味着“能够通过查看代码来判断程序将做什么。”这在大多数语言中都是非常困难的,由于副作用、强制转换、隐式转换、重载函数和运算符等原因,也就是说,当您无法仅使用大脑对代码进行推理时,您必须运行它以查看它对给定输入的作用。

“对程序进行推理”只是“分析程序以查看它的作用”


其思想是,纯洁简化了理解,既可以通过人类改变程序,也可以通过机器编译程序或分析程序中的错误案例。

正如@John Wiegley所说,关于手段的理由

通过查看代码就可以知道程序将做什么


更重要的是理解是什么阻碍了我们对代码进行推理。这些都是副作用

这个问题的许多正确答案都已经给出,参考了正确性的数学证明。但我希望为不一定是数学专业的程序员提供一个实用的答案

正如道格拉斯·克罗克福德(Douglas Crockford)所观察到的那样,正确性的形式证明在当代编程实践中并不是很重要

“关于代码的原因”这句话首先使它变得实用