【问题标题】:Why does my while loop not terminate in this functional language?为什么我的 while 循环不会以这种函数式语言终止?
【发布时间】:2018-06-12 15:34:14
【问题描述】:

我正在尝试使用命令式和函数式概念构建标准 ML 程序,并将内容写入文件。但是我的 while 循环似乎并没有终止,而是连续打印相同的值。

fun writeImage image filename =

  let val ap = TextIO.openOut filename

      val (w,h) = size image

      val row = ref 0

      val stringToWrite = "";

  in

    while !row < h do

        TextIO.output(ap,"A");

        row := !row + 1;

     TextIO.closeOut ap

  end;  

如果我删除了 while 循环后的第一行,则循环终止。但如果我包含TextIO.output(ap,"A");,它不会。为什么会这样?

【问题讨论】:

  • 自从我上次使用 SML 已经有一段时间了,但是您是否尝试在 row := !row + 1; 之后删除 ;

标签: arrays algorithm functional-programming sml smlnj


【解决方案1】:

让我们用正确的缩进编写你的程序,然后就清楚错误在哪里了:

...
while !row < h do
    TextIO.output(ap,"A");
row := !row + 1;
TextIO.closeOut ap
...

你永远循环,因为增量在循环体之外。

你打算这样写:

...
while !row < h do (
   TextIO.output(ap,"A");
   row := !row + 1
);
TextIO.closeOut ap
...

对吗?

我长期以来一直在研究人们在编程时如何犯错误。我很想知道你是怎么犯这个错误的。如果您认为; 的绑定比while 更强,那么您为什么认为TextIO.closeOut ap循环之后?当然,如果您认为; 将增量绑定到循环,那么; 也应该将其绑定到循环。您是否可能认为 ML 是一种类似于 Python 的语言,其中循环结构使用空格作为主体范围的指南?

您对 ML 中的; 有什么更普遍的看法?您是否将; 视为语句终止符,就像在类 C 语言中一样?还是您认为它是对副作用表达式的中缀排序操作?

您在这里的思考过程是什么?工具如何让您在无需寻求帮助的情况下更轻松地解决问题?

【讨论】:

  • 很好的答案!我通常对 ML 中的括号表示法感到非常困惑,而不是 ;。我发现在许多情况下,ML 需要程序员提供非常明确的信息来指导它,这是我假设它不需要的错误。很多时候,我发现以这种方式捕获 exp(a, f a b) 这样的表达式而不是 exp(a, (f a b)) 非常直观,尽管前者有时会给我带来很多错误。在这种情况下,我认为 ; 绑定到 while 循环,而没有分号的则位于 while 循环之外。
  • 更不幸的是,不确定这是好事还是坏事,因为代码在没有括号的情况下工作,我无法在不运行代码的情况下判断它是否可以工作。除非我对这种语言有丰富的经验,否则缺乏一致性使我很难直观地编写代码。
  • 不确定您所说的工具是什么意思,但我认为如果 ML 能够给出一个真正有意义的错误,那将非常有帮助。例如,有时不使用方括号,它告诉我这个特定的值类型没有适用的功能,但它并没有准确地告诉我是哪个值。这是因为我没有使用正确的括号,编译器会看到它,因为我试图将函数应用于另一个值类型,这不是我的意思。同样,缺乏一致性和清晰度会扼杀编码流程。
  • 如我所料,您的困惑在于; 的含义。想想像+ 这样的运算符。当您说let x = y + z in ... 时,很明显+ 将两个表达式转换为一个表达式,这意味着“评估两个操作数并将结果相加作为您的值”。 ;完全一样。它是一个接受两个表达式的运算符,它的意思是“计算左操作数,计算右操作数,并使用右值作为你的值”。 不要; 视为“语句终止符”。它是表达式的运算符,例如+
  • @oldselflearner1959:不客气。我还要注意,在 OCaml 方言中,您可以使用“开始”和“结束”而不是“(”和“)”,这可以使一些这样的结构更容易阅读,因为它使它们看起来更像语句。我认为这些在标准 ML 方言中是不合法的。
猜你喜欢
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 2012-11-07
  • 1970-01-01
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多