6

私は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

4 に答える 4

8

関数型言語でこれを行うには、通常、ループや突然変異の代わりに再帰を使用する必要があるという他の貢献者に同意します。

ただし、本当に変異とループを使用したい場合は、一種の「可変セル」である参照と呼ばれるデータ構造を使用する必要があります。関数で参照を割り当て、ref初期コンテンツを渡します。!演算子を使用してコンテンツにアクセスします。そして、:=演算子を使用して新しいコンテンツを設定します。したがって、上記のコードを直訳すると、次のようになります。ご覧のとおり、構文は非常に醜く、それが人々がそれを避けるもう 1 つの理由です。

fun foo (stuff, counter_start) =
let
  val counter = ref counter_start
in
  while !counter > 0 do (
    bar stuff;
    counter := !counter - 1
  )
end;
于 2009-05-04T00:08:35.807 に答える
6

関数型プログラムでは、変更可能な変数がパラメーター (通常は入れ子になったヘルパー関数) に変わります。

あなたの例では、変更されているのは aleady パラメータであるため、ヘルパー関数は必要ありません。あなたのコードは

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

もちろん、このコードは依然として非常に重要です...呼び出しbar stuffは、純粋に副作用のために実行されます。あまり ML っぽいわけではありません。

于 2009-05-03T23:34:08.310 に答える
5

短い答え:あなたはしません。関数型プログラミングでは、通常、変数を変更することはありません。つまり、ループは不可能です。代わりに、再帰を使用して同じことを実装できます。同様に、一般的に言えば、副作用がないため、関数呼び出しはデータを返す場合にのみ意味があります。したがって、bar(stuff) はおそらくあまり役​​に立ちません。アプリケーションの残りの部分に影響を与える方法はありません。関数型プログラミング スタイルでは、 bar() 関数は毎回異なるデータに対して呼び出され、アプリケーションの残りの部分が動作できる何かを返す必要があります。

(ML は場合によっては副作用を許容しますが、簡単にするために、今は無視しましょう)

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

もう少し詳しく教えていただければ、プログラムの書き方をより具体的に説明できます。しかし、そのままでは、あなたのプログラムは機能的なスタイルでは意味を成しません。

于 2009-05-03T23:35:39.287 に答える
2

私は ML を知りませんが、これは ML のような疑似コードです。

楽しい foo のもの 0 = return ()
  | | foo スタッフ カウンター = (バー スタッフ; foo スタッフ (カウンター - 1))

ML でコマンドを「チェーン」する方法がわかりません。セミコロンは単なるプレースホルダーです。

通常、ループすることはありません。私はむしろ通常の高階関数を期待したいと思います。それらに慣れると、ループを手動で記述することは、アセンブラーをコーディングするように感じられます。

編集:コメントに従ってコードを修正

于 2009-05-04T01:27:53.213 に答える