0

要するに、F# で「再帰的なリスト内包表記」を行う最も慣用的な方法は何ですか?

詳細: これまでに学んだように (私は F# は初めてです)、リストを「構築」するための基本的に次のツールがあります: List.map とリスト内包表記。私見では、どちらも多かれ少なかれ同じことを行います。指定されたリストの要素を「変更」することによってリストを生成します(理解の場合、指定されたリストは[k..n]の形式です)。

私がやりたいことは、帰納的にリストを構築することです(人々が尋ねる前に:好奇心以外の理由ではありません)つまり、「List.maplist」のようなものと呼ばれる関数から期待される動作を備えた組み込み関数があります。引数として

関数 f : 'a List -> 'a および n : int,

リストを返す

[...; f (f []) ; 長さ n の f [] ]。

私が何を意味するかを説明するために、私は自分でそのような関数を書きました(演習として)

let rec recListComprehension f n =
    if n=0 then []
    else
        let oldList = recListComprehension f (n-1)
        f (oldList) :: oldList 

または少し読みにくいですが、末尾再帰的です:

let rec tailListComprehension f n list = 
    if n=0 then list
    else tailListComprehension f (n-1) ((f list)::list)

let trecListComprehension f n = tailListComprehension f n []

たとえば、最初の 200 個のフィボナッチ数を含むリストは次のように生成できます。

let fiboGen =
    function
    | a::b::tail -> a+b
    | _ -> 1UL

trecListComprehension (fiboGen) 200

質問を要約すると、多かれ少なかれ「trecListComprehension」のように動作する関数が F# に組み込まれていますか?そうでない場合、この種の機能を実現する最も慣用的な方法は何ですか?

PS: 少し冗長で申し訳ありません..

4

3 に答える 3

2

あなたは基本的foldに数値範囲を超えています。したがって、次のように書くことができます。

let listComp f n = List.fold (fun xs _ -> f xs :: xs) [] [1 .. n]

これには、 の負の値を適切に処理できるという追加の利点がありnます。

于 2013-05-07T22:20:00.660 に答える