使用Haskell循环一组函数

sub*_*ray 2 recursion haskell loops list-comprehension while-loop

这是一个简单的,准确的例子,说明我试图用C++编写的代码.

while (state == true) {
  a = function1();
  b = function2();
  state = function3();
}
Run Code Online (Sandbox Code Playgroud)

在我正在研究的程序中,我需要循环一些函数,直到bool 状态等于false(或直到其中一个变量,假设变量b,等于0).

如何在Haskell中完成此代码?我在这里搜索过,谷歌甚至Bing都没有找到关于如何使用函数重复操作的任何明确,直接的解释.

任何帮助,将不胜感激.

Ing*_*ngo 5

考虑到丹尼尔斯的评论,它可能看起来像这样:

f = loop init_a init_b true
    where
         loop a b True = loop a' b' (fun3 a' b')
             where
                 a' = fun1 ....
                 b' = fun2 .....
         loop a b False = (a,b)
Run Code Online (Sandbox Code Playgroud)

  • @SubtleArray我认为你误解了一些东西,上面的代码定义了一个叫做循环的函数.它没有使用任何原始循环结构(可能除了递归). (2认同)

Lui*_*las 5

好吧,这是关于如何在此处映射概念的建议:

  • C ++循环是Haskell中某种形式的列表操作。
  • 循环的一次迭代=处理列表的一个元素。
  • 循环直到某个条件变为真=在列表上递归的函数的基本情况。

但是命令式循环和函数列表函数之间有一些关键的区别:循环描述了如何进行迭代;高阶列表函数描述了计算的结构。因此,例如map f [a0, a1, ..., an]可以通过以下图表进行描述:

[a0,   a1,   ..., an]
 |     |          |
 f     f          f
 |     |          |
 v     v          v
[f a0, f a1, ..., f an]
Run Code Online (Sandbox Code Playgroud)

请注意,这说明结果如何与论点f[a0, a1, ..., an],迭代没有表现如何一步一步来。

同样,foldr f z [a0, a1, ..., an]对应于此:

f a0 (f a1 (... (f an z)))
Run Code Online (Sandbox Code Playgroud)

filter 虽然不太适合绘制图表,但是很容易说明它满足的许多规则:

  • length (filter pred xs) <= length xs
  • 对于每一个元素xfilter pred xspred xTrue
  • 如果x是的元素filter pred xs,则x是的元素xs
  • 如果x不是的元素xs,则x不是的元素filter pred xs
  • 如果x出现在x'filter pred xs,则x出现在x'中,xs
  • 如果x出现前x'xs,都xx'出现在filter pred xs,然后x出现之前x'filter pred xs

在经典命令式程序中,所有这三种情况都写为循环,它们之间的区别归结于循环体的作用。相反,函数式编程坚持认为这种结构模式不属于“循环体”(这些函数fpred这些示例中);相反,这些图案是最抽象到高阶功能,如mapfoldrfilter。因此,每次看到这些列表函数之一时,您都立即知道一些有关参数与结果如何关联的重要事实,而无需阅读任何代码。而在典型的命令式程序中,您必须阅读循环主体才能弄清楚这些内容。

因此,对您问题的真正答案是,在不知道循环主体在做什么的情况下,不可能将命令式循环惯用地转换为功能性术语-循环运行之前应该具备的前提是什么,以及假定的后置条件是什么是循环结束的时间。因为您仅模糊地描述了该循环体,将确定计算的结构,因此不同的结构将在Haskell中调用不同的高阶函数。