7

私は ocaml を初めて使用し、スタイル関数を渡す継続を記述しようとしていますが、k の追加の引数にどの値を渡す必要があるかについて非常に混乱しています

たとえば、リストのすべての要素が偶数の場合は true、それ以外の場合は false を返す再帰関数を作成できます。

そのように

let rec even list = .... 

CPSでは、関数を渡すために1つの引数を追加する必要があることを知っています

let rec evenk list k = .... 

しかし、私はこのkをどのように扱うか、そしてこれがどのように正確に機能するのか見当がつかない

たとえば、この偶数関数の場合、環境は次のようになります

val evenk : int list -> (bool -> ’a) -> ’a = <fun>

evenk [4; 2; 12; 5; 6] (fun x -> x)  (* output should give false *)
4

4 に答える 4

12

継続kは、から結果をevenk取得して「残りの計算」を実行し、「答え」を生成する関数です。答えのタイプと「残りの計算」の意味は、CPSを何に使用しているかによって異なります。CPS は通常、それ自体が目的ではありませんが、何らかの目的を念頭に置いて行われます。たとえば、CPS 形式では、制御演算子を実装したり、テール コールを最適化したりするのは非常に簡単です。何を達成しようとしているのかを知らなければ、質問に答えることは困難です。

価値があるのは、単に直接スタイルから継続渡しスタイルに変換しようとしていて、関心があるのが答えの値だけである場合、継続として恒等関数を渡すことはほぼ正しいことです。

次の良いステップは、evenkCPS を使用して実装することです。より簡単な例を示します。直接スタイル機能がある場合

let muladd x i n = x + i * n

mulkCPS プリミティブとを仮定するとaddk、次のように記述できます。

let muladdk x i n k =
  let k' product = addk x product k in
  mulk i n k'

そして、掛け算が最初に行われ、次に加算を行う で「継続」しk'、最後に呼び出し元に戻る でそれが行われることがわかります。重要なアイデアは、 I の本体内に、乗加算関数の中間点を表す新しい継続を割り当てるということです。作業を行うには、そのような継続を少なくとも 1 つ割り当てる必要があります。continueskmuladdkk'evenk

これが役立つことを願っています。

于 2010-06-18T23:11:36.857 に答える
8

私が CPS で遊んだときはいつでも、継続に渡されるものは、通常呼び出し元に返すものです。この単純なケースでは、「直観潤滑剤」として、継続に「リターン」という名前を付けることをお勧めします。

let rec even list return =
  if List.length list = 0
    then return true
    else if List.hd list mod 2 = 1
      then return false
      else even (List.tl list) return;;

let id = fun x -> x;;

使用例: "even [2; 4; 6; 8] id;;".

于 2010-06-20T23:54:24.277 に答える
6

evenk(恒等関数を使用して - 継続渡しスタイルを通常のスタイルに効果的に変換する) correctの呼び出しがあるので、難しさは定義にあると思いevenkます。

kノーマンが言ったように、残りの計算を表し、最終的な値を生成する継続関数です。したがって、あなたがする必要があるのは、 の結果を計算し、その結果をveven渡し、単にkを返すのk vではなく返すことvです。

于 2010-06-19T01:26:08.973 に答える
1

継続渡しスタイルで書かれていないかのように、関数の結果を入力として与えたい。

リストに偶数の整数しかないかどうかをテストする関数は次のとおりです。

(* val even_list : int list -> bool *)
let even_list input = List.for_all (fun x -> x mod 2=0) input

続きを書いてみましょうcont:

(* val evenk : int list -> (bool -> 'a) -> 'a *)
let evenk input cont =
  let result = even_list input in
  (cont result)

関数の結果を計算resultし、継続に渡します...

于 2011-04-20T10:36:56.190 に答える