2017-11-04 6 views
2

私は、リストのタプルを与え、combine機能を作成し、タプルのリストを返します:合理的ネスティング機能

let rec combine = 
fun (l1, l2) -> 
    match (l1, l2) with 
    | ([], [])   -> [] 
    | (x::xs, y::ys) -> (x, y)::(combine xs ys) 

は、その後、私は同じように動作し、同様の機能foo56を構築しましたが、4つのリストではなく、二。

let rec foo76 =  //Combine a 4-tuple of lists in a list of 4-tuples 
fun (l1, l2, l3, l4) -> 
    match (l1, l2, l3, l4) with 
    ([], [], [], [])    -> [] 
    | (x::xs, y::ys, z::zs, t::ts) -> 
     (x, y, z, t)::(foo76 (xs, ys, zs, ts)) 

問題:私はそれがcombineて動作させるためにfoo56を実装したいと思います。私は失敗したいくつかの試みをしました。ここでは、有望な(ため息)ほとんどは次のとおりです。

let foo76combine =  //Combine a 4-tuple of lists in a list of 4-tuples 
    fun (l1, l2, l3, l4) -> 
     match (l1, l2, l3, l4) with 
     ([], [], [], [])    -> [] 
     | (x::xs, y::ys, z::zs, t::ts) -> 
      (x, y, z, t)::(combine(combine(combine (xs, ys) zs) ts)) 

私は再帰的に自分自身でどのように巣combine適切に可視化することに失敗します。それは私の経験不足のためかもしれない、と私は思います。私は、少なくとも、正しい方法でですか?ただfoo76を働かせるだけではありません。私はこのアプローチの実用的な使い方をよりよく把握し、問題をより小さな部分で分解できるようにすることに興味があります。

答えて

4

あなたは単にcombineを構成するだけであなたが望むものを手に入れることはできません。最も内側のcombineは期待どおりに動作し、('a * 'b) listを返しますが、次の数字は('a * 'b) list'c listで、('a * 'b * 'c) listではなく(('a * 'b) * 'c)) listとなります。

タプルは単純にそのようには動作しません。タプルは任意の長さのタプルには一般化できません。そのため、一般的なList.zipNではなく、List.zipList.zip3の機能が別々に存在します。異なるタプルサイズを扱いたい場合は、それぞれ異なるタプル関数が必要です。

結果的に "入れ子になった"タプルを4タプルにマッピングすることで、これを少しでも補うことができますが、combineを再利用するために得られるものは、私の意見では面倒なことではありません。それは読みにくく、 foo76のような専用の機能に:

let rec zip4 (l1, l2, l3, l4) = 
    match l1, l2, l3, l4 with 
    | [], [], [], []    -> [] 
    | x::xs, y::ys, z::zs, t::ts -> 
     (x, y, z, t) :: 
      (List.map 
       (fun (((a,b),c),d) -> (a,b,c,d)) 
       (combine(combine(combine(xs, ys), zs), ts))) 
+0

これは非常に良い点です。私はいつか少しでも練習をします、ありがとう! – Worice

2

List.zipあなたcombine関数に似ている既存の関数です。 List.zip3もありますが、リストは3つですが、List.zip4は組み込まれていません。あなたはこれをList.zipのように以下のように定義することができます:

let zip4 a b c d = 
    a 
    |> List.zip b 
    |> List.zip c 
    |> List.zip d 
    |> List.map (fun (d, (c, (b, a))) -> (a, b, c, d)) 
+0

このアプローチは非常にエレガントです、ありがとう! – Worice