0

関数型言語でのプログラミングは初めてです。F# collect for list を実装しようとしています。

let rec collect func list =
     match list with
     | [] -> []
     | hd::tl -> let tlResult = collect func tl 
                 func hd::tlResult;;

collect (fun x -> [for i in 1..3 -> x * i]) [1;2;3];;

印刷する必要があります:

val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]

しかし、私は得ました:

val it : int list = [[1; 2; 3;], [2; 4; 6;], [3; 6; 9]]
4

2 に答える 2

3

collectこれは、大きなリストのスタック オーバーフローを起こさない末尾再帰です。

let collect f xs =
    let rec prepend res xs = function
        | [] -> loop res xs
        | y::ys -> prepend (y::res) xs ys
    and loop res = function
        | [] -> List.rev res
        | x::xs -> prepend res xs (f x)
    loop [] xs

やや不正行為であるより単純なバージョンは次のとおりです。

let collect (f: _ -> list<_>) (xs: list<_>) = [ for x in xs do yield! f x ]
于 2014-11-10T17:02:20.123 に答える
2

この関数を関数型スタイルで効率的に実装するのは難しいですが、リストを連結する演算子をcollect使用して非常に簡単に実装できます。@

let rec collect f input =
  match input with
  | [] -> []
  | x::xs -> (f x) @ (collect f xs)  
于 2014-11-10T02:07:25.513 に答える