2012-02-09 12 views
2

可能性の重複:
F# - cross product of two lists
Projecting a list of lists efficiently in F#デカルト積二つのリスト

私は2つの整数のリストを受け取り、すべてのデカルト製品を単一のリストを返す関数を持っています。私は正しいアイデアを持っているが正しい実装ではないと思う。私はいくつかのポインタを得ることができますか?

let rec cartesian = function 
| ([],[]) -> [] 
| (xs,[]) -> [] 
| ([],ys) -> [] 
| (x::xs,ys) -> List.map(fun y -> (x,y)::[]) cartesian (xs,ys) 
+0

をすでにFSSnipに存在しています。 –

答えて

6

これは、簡単な修正は次のとおりです。

let rec cartesian = function 
| ([],[]) -> [] 
| (xs,[]) -> [] 
| ([],ys) -> [] 
| (x::xs, ys) -> (List.map(fun y -> x,y) ys) @ (cartesian (xs,ys)) 

アイデアは、各要素xで、あなたがリスト[(x, y1); (x, y2); ...; (x, yn)]を生成し、完全にこれらのリストを連結していることです。

あなたの関数では、最初のパターンマッチングケースは冗長です。そして、議論はカレーの形になる方がより便利です。この関数は次のようになります。

let rec cartesian xs ys = 
    match xs, ys with 
    | _, [] -> [] 
    | [], _ -> [] 
    | x::xs', _ -> (List.map (fun y -> x, y) ys) @ (cartesian xs' ys) 

あなたのアイデアを理解すれば、あなたは、高次機能List.collectが完全タスク一致していることがわかります。このケースを処理するコードはもちろん

let cartesian xs ys = 
    xs |> List.collect (fun x -> ys |> List.map (fun y -> x, y)) 
+0

あなたはこの部分を説明してもらえますかList.map(fun y - > x、y)ys)...またlist.map関数がどのリストを使うのか知っているのは困惑しています..この場合ysではなくxs – user1072706

+1

あなたは 'xs'を分解しているので、' x'要素ごとに 'ys'全体を走査して'(x、yi) 'の組を生成する必要があります。結局、結果は全ての対のリスト '(xi、yi)'であり、最初のリストから 'xi'が、第2リストからは' yi'です。 – pad

+0

詳しい説明はありがたいです。 – user1072706

関連する問題