函数式编程是否表现出控制流?

Does functional programming exhibit control flow?

提问人: 提问时间:7/25/2020 更新时间:7/25/2020 访问量:861

问:

函数式编程必须处理与其他所有范式相同的编程方面。没有什么是消失的,而是通过不同的抽象隐藏起来的。我经常读到控制流只与语句相连,因此 FP 没有表现出任何作用。我认为这种说法具有误导性。

有一个完整的类型类来对命令式控制流 (Monad) 进行建模。运算符具有优先级和关联性,其他临时类型遵循进一步的算术定律(按照惯例)。有 // 和语句。懒惰必须被考虑在内。ifthenelsecase

关联性可能对控制流的影响最大,因为它很常见,并且允许并行计算。因此,即使控制流不再那么明显,但仍然有一个,对吧?

但也许我只是将评估和执行顺序混为一谈。希望这个问题不要太宽泛。

Haskell 函数式编程 语言与控制

评论

0赞 willeM_ Van Onsem 7/25/2020
在 lambda 演算(FP 背后的理论框架)中,评估顺序对于正确的结果无关紧要 (en.wikipedia.org/wiki/Lambda_calculus#Reduction_strategies)。当然,一种评估策略优于另一种评估策略可以导致更多的减少(所以如果你愿意的话,可以“计算”)。

答:

3赞 chi 7/25/2020 #1

从理论上讲,纯函数式编程允许使用多种策略来计算表达式。不同的语言实现可以决定使用不同的策略来减少表达式。例如,我们可以先评估、先评估,甚至同时评估两者。e1 + e2e1e2

要评估,我们可以先评估,然后只评估相应的分支。原则上,我们甚至可以开始并行计算所有 、 和 ,并终止与未获取的分支对应的线程。或者我们甚至可以使用一种更奇怪的方法,我们尝试使用静态分析来证明终止:如果成功,并且 和 终止之前的并行计算为两个相等的值,我们只需返回它并杀死仍在评估的线程,因为我们发现我们根本不需要它。if guard then e1 else e2guardguarde1e2guarde1e2guardguard

有几篇关于如何使用图约简技术在 lambda 演算中执行“最优约简”的论文。

由于这些不同的策略最终会得出相同的结果,因此除了性能原因外,在它们之间进行选择是无关紧要的。

在实践中,GHC减少策略并不那么激进。它不会自动并行化任何内容。如果我没记错的话,它不遵循“最优还原”算法,而是一种更直接的算法,其中包含一系列优化和技巧来利用现代硬件。GHC 过去采用推入式抽象机器,但从那时起,当它变得更快时,它转向了更直接的评估/应用机器。

GHC 抽象机(STG 机)使用一种策略,使表达式具有固定的计算顺序。如果您愿意,可以将其视为“控制流”:始终首先评估,然后仅评估选定的分支。if then elseguard

了解所采用的策略有助于评估程序的复杂性(即使由于懒惰,这在 GHC Haskell 中仍然是一项艰巨的任务)。为此,从某种意义上说,我们需要知道策略使用的“控制流”。

但是,在评估程序的正确性时,策略并不重要。如果我们想证明我们的程序是正确的,我们不需要假设一个特定的评估策略,因为所有这些策略都会产生相同的结果。

评论

0赞 7/26/2020
感谢您耐心回答我的基本问题。