2009-05-03 5 views
4

私は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? 
をデクリメントします

答えて

6

機能的なプログラムでは、可変変数がパラメータに変換され、通常はネストされたヘルパー関数になります。

あなたの例では、変異しているものがaleadyパラメータであるため、ヘルパー関数は必要ありません。あなたのコードはもちろん

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

なり、このコードはまだでひどく不可欠...コールbar stuffは、副作用のために純粋に実行されます。それほどML-ishではありません。

+1

+1をコメントによると、インデント! – diapir

+0

@diapir:バハー、セミコロンのプレースメントについては、コンテンツよりも気にしていれば、-1を与えるだろう。 – Svante

+0

@Svante:何が私の頭を通過したのかわからない、私は実際にそれを0騒ぎを与えるだろう。 – diapir

5

短い答え:あなたはしていません。関数型プログラミングでは、一般に変数を変更することはありません。つまり、ループは不可能です。代わりに、再帰を使用して同じものを実装できます。同様に、一般的に言って副作用がないので、関数呼び出しはデータを返すだけで意味があります。だから、バー(stuff)はあまり有用ではないでしょう。アプリケーションの残りの部分に影響する方法はありません。関数型プログラミングでは、毎回bar()関数を別のデータで呼び出す必要があり、アプリケーションの残りの部分が処理できるものを返す必要があります。

(MLが一定の場合には副作用を許可していますが、今のところそれを無視してみましょう、物事をシンプルに保つために)

正確に何を達成しようとしていますか? (何をループする必要がありますか、関数は何をしますか?

さらに詳しく説明すると、プログラムの書き方を具体的に説明することができます。機能的なスタイルで意味をなす。

6

を、私はあなたが一般的に関数型言語でこれを行うには、ループや突然変異の代わりに再帰を使用する必要があり、他の貢献者に同意する。

あなたが本当にかかわらず、変異を使用したいとループしている場合「可変セル」のような参照と呼ばれるデータ構造を使用する必要があります。ref関数で参照を割り当て、初期の内容を渡します。内容は!演算子を使用しています。そして、:=演算子を使用して新しいコンテンツを設定しました。上記のコードのリテラル変換は、次のようなものになります。ご覧のとおり、構文は実際には醜いので、それが人々がそれを避けるもう一つの理由です。

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

私はMLを知らないが、これは、いくつかのML-のような擬似コードです:「チェーン」はMLでのコマンドにする方法

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

は、私にはわかりません。セミコロンは単なるプレースホルダです。

通常、ループしません。私はむしろ通常の高次関数を期待しています。それらに慣れると、手作業でループを書くことはアセンブラのコーディングのように感じるでしょう。

編集:固定コードについて

+1

セミコロンが関数の定義よりも優先順位が低いため、連鎖したコマンドをかっこで囲む必要があることを除いて、これはかなり正しいことです。 また、OPは、カウンターが0のときにアクションが0回実行されることを望んでいたと思います。そのため、最初のケースでは、「バー・スタッフ」はしません。代わりに "()"(単位)を返すだけです。 – newacct

+1

参考までに、mlでreturnキーワードを使用する必要はありません。関数の戻り値は、常に関数の最後の式です。 – shleim