3

私は現在、Scalazノンブロッキング先物(別名)で遊んでいます。約束。次の関数を末尾再帰にするのに苦労しています。

@tailrec
private def repeat( res: Promise[I] ):Promise[I] =
  res map p flatMap { 
    (b:Boolean) =>
      if( b ) repeat( res flatMap f ) else res
  }

ここpで、はtypeの述語であり、I=>Booleanはtypefの並行関数I=>Promise[I]です。

メソッドはアノテーションなしでコンパイルされます。

ヒントはありますか?ありがとう

4

2 に答える 2

4

あなたの方法はまったく再帰的ではありません。res別のスレッドで実行されている可能性のある計算です。res map p flatMap fあなたの方法に関する限り、すぐに約束を返します。の再発repeatは別のプロセスで発生します。

もう少し簡潔に言えば、Promiseは継続モナドであり、flatMap呼び出しは自動的に継続渡しスタイルに変換されます。

于 2011-05-10T04:22:25.050 に答える
1

呼び出しはコード内で1回だけ表示されるため、これは末尾再帰に見えますが、コレクション内の要素ごとに1つずつ、複数の再帰呼び出しがあります。少なくとも、それはコンパイラーが見るものです。(これがいくつかのコレクションのflatMapであると仮定します。何pが返されるのかわかりません)

再帰を無名関数としてどこかに渡します。どれくらいの頻度で実行されるかは誰にもわかりません。

于 2011-05-09T13:57:32.190 に答える