函数式编程必须处理与每一个其他范例相同的编程方面。没有什么东西只是消失了,而是通过不同的抽象而隐藏起来的。我经常读到,控制流只与语句连接,因此FP没有显示。我认为这句话有误导性。
有一个完整的类型类来建模命令式控制流(Monad)。运算符具有优先性和相干性,其他自组织类型遵循进一步的算术规则(按惯例).有if/then/else和case语句。必须考虑到懒散。
相联性对控制流的影响可能最大,因为它是常见的,允许并行计算。所以,即使控制流不再那么明显,仍然有一个,对吗?
但也许我只是把评估和执行顺序混为一谈。希望这个问题不要太宽泛。
发布于 2020-07-25 09:48:32
理论上,纯函数编程允许使用多种策略计算表达式。不同的语言实现可以决定使用不同的策略来减少表达式。例如,在e1 + e2中,我们可能首先计算e1,先计算e2,甚至并行计算两者。
要评估if guard then e1 else e2,我们可以先计算guard,然后只计算相应的分支。原则上,我们甚至可以并行地评估所有guard、e1和e2,并关闭对应于未取分支的线程。或者我们甚至可以使用一种更奇怪的方法,我们试图用静态分析来证明guard终止:如果成功的话,而e1和e2的并行计算在guard之前终止为两个相等的值,我们只需要返回这个值,并关闭仍然在计算guard的线程,因为我们发现我们毕竟不需要它。
关于如何使用图约简技术在lambda演算中执行“最优约简”,有几篇论文。
由于这些不同的策略最终达到了相同的结果,因此,除了性能方面的原因之外,在它们之间进行选择是无关紧要的。
在实践中,GHC削减战略并不那么激进。它不会自动并行任何东西。如果我没记错的话,它不遵循“最优约简”算法,而是使用大量优化和技巧来开发现代硬件的更直接的算法。GHC过去常采用push/enter抽象机器,但从那时起,当它变得更快时,它就转向了一个更简单的eval/apply。
GHC抽象机器(STG机)使用一种策略,使像if then else这样的表达式具有固定的计算顺序。您可以将其看作是“控制流”,如果您愿意的话:总是首先对guard进行评估,然后只计算选定的分支。
了解使用的策略有助于评估程序的复杂性(即使在GHC Haskell中,由于懒惰,这仍然是一项艰巨的任务)。为此,从某种意义上说,我们需要知道策略所使用的“控制流”。
然而,在评估程序的正确性时,策略并不重要。如果我们想证明我们的程序是正确的,我们不需要假设一个特定的评估策略,因为所有这些都会产生相同的结果。
https://stackoverflow.com/questions/63086136
复制相似问题