【问题标题】:Loops in SML/NJSML/NJ 中的循环
【发布时间】:2010-10-23 12:44:20
【问题描述】:

我是 SNL/NJ 的新手,想知道如何才能完成以下任务:

foo(stuff,counter)
{
   while(counter > 0)
   {
     bar(stuff);
     counter-1;
   }
   return;
}

类似这样的东西,但是我该如何减少呢?:

foo(stuff,counter) = 
   while counter > 0 do bar(stuff) ??? // how do I decrement counter here?

【问题讨论】:

    标签: functional-programming sml


    【解决方案1】:

    我不懂 ML,但这是一些类似 ML 的伪代码:

    有趣的 foo 东西 0 = return () | foo stuff counter = (bar stuff; foo stuff (counter - 1))

    我不知道如何在 ML 中“链接”命令;分号只是一个占位符。

    通常,您不会循环播放。我宁愿期待通常的高阶函数。当你习惯了这些,手动编写循环会感觉像编码汇编程序。

    编辑:根据注释修复代码

    【讨论】:

    • 这非常正确,除了您需要将链接的命令括在括号中,因为分号的优先级低于函数定义。另外,我认为 OP 希望在计数器为 0 时执行 0 次操作,因此在第一种情况下,您可能不会执行“bar stuff”;而只是返回“()”(单位)。
    • 仅供参考,不需要在 ml 中使用 return 关键字。函数的返回值始终是函数中的最后一个表达式。
    【解决方案2】:

    我同意其他贡献者的观点,即您通常应该使用递归而不是循环和变异来在函数式语言中执行此操作。

    如果你真的想使用变异和循环,你需要使用一种称为引用的数据结构,它是一种“可变单元”。您使用ref 函数分配引用,并将初始内容传递给它。您可以使用! 运算符访问内容。然后使用:= 运算符设置新内容。因此,您上面的代码的字面翻译将类似于以下内容。如您所见,语法真的很丑陋,这也是人们避免使用它的另一个原因。

    fun foo (stuff, counter_start) =
    let
      val counter = ref counter_start
    in
      while !counter > 0 do (
        bar stuff;
        counter := !counter - 1
      )
    end;
    

    【讨论】:

      【解决方案3】:

      简短的回答:你不知道。在函数式编程中,您通常从不修改变量,这意味着循环是不可能的。相反,您可以使用递归来实现相同的功能。同样,由于一般来说没有副作用,因此函数调用只有在返回数据时才有意义。所以 bar(stuff) 可能不是很有用。它无法影响应用程序的其余部分。在函数式编程风格中,您的 bar() 函数应该每次都在不同的数据上调用,并返回应用程序的其余部分可以执行的操作。

      (ML 在某些情况下确实允许副作用,但为了简单起见,我们暂时忽略它)

      您到底想达到什么目的? (需要循环什么,函数有什么作用?

      如果您提供更多细节,我们可以更具体地解释您应该如何编写程序。但事实上,您的程序在函数式风格中根本没有意义。

      【讨论】:

        【解决方案4】:

        在函数式程序中,可变变量变成参数,通常是嵌套的辅助函数。

        由于在您的示例中,被变异的东西是一个leady 参数,因此不需要辅助函数。你的代码变成了

        fun foo stuff counter =
          if counter > 0 then
            ( bar stuff
            ; foo stuff (counter-1)
            )
          else
            ()
        

        当然,这段代码仍然非常命令式...调用bar stuff 纯粹是为了副作用而执行的。不是很像机器学习。

        【讨论】:

        • @diapir:呸,如果我更关心分号位置而不是内容,我会给 -1。
        • @Svante:不知道我脑子里想的是什么,实际上我会大惊小怪。
        猜你喜欢
        • 2011-11-24
        • 2010-10-15
        • 2010-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多