リスト内包表記は、これを行う最も簡単な方法です。
let allpairs L =
[for x in L do
for y in L -> (x*y)]
または、ループを使用せずに:
let pairs2 L = L |> List.collect (fun x -> L |> List.map (fun y -> (x*y)))
コメントに応じて編集: 次
のように、自己交差拡張メソッドをリストに追加できます。
type Microsoft.FSharp.Collections.List<'a> with
member L.cross f =
[for x in L do
for y in L -> f x y]
例:
> [1;2;3].cross (fun x y -> (x,y));;
val it : (int * int) list =
[(1, 1); (1, 2); (1, 3); (2, 1); (2, 2); (2, 3); (3, 1); (3, 2); (3, 3)]
私自身は F# で拡張メソッドを使用しませんが、少し C# っぽいと感じています。しかし、それは主に、F# で流暢な構文が必要だとは思わないためです。通常、関数をパイプ (|>) 演算子で連結しているためです。
私のアプローチは、タイプ自体ではなく、クロス関数で List モジュールを拡張することです。
module List =
let cross f L1 L2 =
[for x in L1 do
for y in L2 -> f x y]
これを行うと、リストの他のメソッドと同じように cross メソッドを使用できます。
> List.cross (fun x y -> (x,y)) [1;2;3] [1;2;3];;
val it : (int * int) list =
[(1, 1); (1, 2); (1, 3); (2, 1); (2, 2); (2, 3); (3, 1); (3, 2); (3, 3)]
> List.cross (*) [1;2;3] [1;2;3];;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]