SML / NJ中的循环

时间:2009-05-03 23:29:59

标签: functional-programming sml

我对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?

4 个答案:

答案 0 :(得分:7)

我同意其他贡献者的意见,你通常应该使用递归而不是循环和变异来用功能语言来做这件事。

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

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

答案 1 :(得分:6)

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

因为在你的例子中,被变异的东西是aleady参数,所以不需要辅助函数。您的代码变为

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

当然这段代码仍然非常命令式......调用bar stuff纯粹是为了副作用而执行的。不是ML-ish。

答案 2 :(得分:5)

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

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

你到底想要达到什么目的? (你需要循环什么,这些功能有什么作用?

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

答案 3 :(得分:2)

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

fun foo stuff 0 = return ()
  | foo stuff counter = (bar stuff; foo stuff (counter - 1))

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

通常,你不会循环。我宁愿期待通常的高阶函数。当你习惯了那些,手动编写一个循环就像编写汇编程序一样。

编辑:根据评论修改代码