2017-12-15 7 views
3

上のF#の継続ベースの末尾再帰私はint型を取り、リストの先頭に追加し、私は自分自身を乗算して再帰的に呼ばれているこの非常に単純な関数があります。今リスト

let rec f i = function 
    | [] -> [] 
    | x::xs -> (x+i)::f (i*i) xs 

f 2 [1;2;3] 
val it : int list = [3; 6; 19] 

を、私は私は継続を使ってそれを書き直そうとしていますが、私はちょっと立ち往生しています。ここで私は、これまでに作ってみたものです:私が間違ってやっているものに

let fC i l = 
    let rec loop cont = function 
     | [] -> [] 
     | x::xs -> cont(x+i)::loop (fun acc -> (acc*acc)) xs 
    loop id l 

fC 2 [1;2;3] //Expected [3;6;19] 
val it : int list = [3; 16; 25] 

任意のヒント?

+2

それは末尾再帰ではないですが、多分あなたはそこに得るのを助ける: は、FC I L = = RECループ続きを聞かせて機能 をしましょう| [] - > [] |あなたが上記のリンクからQを注意深く読んで、以前のQの答えを読んでいれば、x :: xs-> x + cont(i):: loop(fun acc-> cont(acc * acc))xs ループid l – DevNewb

+0

あなたの関数を新しいバージョン –

+0

に簡単に変換します@FoggyFinderそれは重複ではない、その質問はCPSとまったく同じではないテール再帰について尋ねます。 – Gustavo

答えて

5

この質問とコメントを見ると、混乱があるようです。

テール再帰は、継続継承スタイル(CPS)を意味する必要はありません。

はここCPS内の関数です:

let f' i p = 
    let rec loop i p k = 
     match p with 
     | [] -> k [] 
     | x::xs -> loop (i*i) xs (fun a -> k ((x+i)::a)) 
    loop i p id 

そして、もちろん、それは尾の再帰的です。しかし、あなたはまた、アキュムレータの代わりに、継続を使ってそれを末尾再帰を書き込むことができます。

let f'' i p = 
    let rec loop i p acc = 
     match p with 
     | [] -> acc 
     | x::xs -> loop (i*i) xs ((x+i)::acc) 
    loop i p [] |> List.rev 

は、より良いCPSを理解することもanswer to this questionを参照してください。

関連する問題