Skip to content

Commit 2ffb0b6

Browse files
committed
Merge pull request #989 from PatrickMcDonald/allPairs
Implement allPairs on List, Seq and Array modules
2 parents 22ba027 + 4f76b0e commit 2ffb0b6

18 files changed

+206
-0
lines changed

src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs

+28
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ type ArrayModule() =
4141
()
4242

4343

44+
[<Test>]
45+
member this.AllPairs() =
46+
// integer array
47+
let resultInt = Array.allPairs [|1..3|] [|2..2..6|]
48+
if resultInt <> [|(1,2);(1,4);(1,6)
49+
(2,2);(2,4);(2,6)
50+
(3,2);(3,4);(3,6)|] then Assert.Fail()
51+
52+
// string array
53+
let resultStr = Array.allPairs [|"A"; "B"; "C" ; "D" |] [|"a";"b";"c";"d"|]
54+
if resultStr <> [|("A","a");("A","b");("A","c");("A","d")
55+
("B","a");("B","b");("B","c");("B","d")
56+
("C","a");("C","b");("C","c");("C","d")
57+
("D","a");("D","b");("D","c");("D","d")|] then Assert.Fail()
58+
59+
// empty array
60+
if Array.allPairs [||] [||] <> [||] then Assert.Fail()
61+
if Array.allPairs [|1..3|] [||] <> [||] then Assert.Fail()
62+
if Array.allPairs [||] [|1..3|] <> [||] then Assert.Fail()
63+
64+
// null array
65+
let nullArr = null:string[]
66+
CheckThrowsArgumentNullException (fun () -> Array.allPairs nullArr nullArr |> ignore)
67+
CheckThrowsArgumentNullException (fun () -> Array.allPairs [||] nullArr |> ignore)
68+
CheckThrowsArgumentNullException (fun () -> Array.allPairs nullArr [||] |> ignore)
69+
70+
()
71+
4472
[<Test>]
4573
member this.Append() =
4674
// integer array

src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs

+12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ open NUnit.Framework
88
open FsCheck
99
open Utils
1010

11+
let allPairs<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) =
12+
let s = xs |> Seq.allPairs xs2
13+
let l = xs |> List.allPairs xs2
14+
let a = xs |> Seq.toArray |> Array.allPairs (Seq.toArray xs2)
15+
Seq.toArray s = a && List.toArray l = a
16+
17+
[<Test>]
18+
let ``allPairs is consistent`` () =
19+
Check.QuickThrowOnFailure allPairs<int>
20+
Check.QuickThrowOnFailure allPairs<string>
21+
Check.QuickThrowOnFailure allPairs<NormalFloat>
22+
1123
let append<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) =
1224
let s = xs |> Seq.append xs2
1325
let l = xs |> List.append xs2

src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs

+22
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,28 @@ type ListModule() =
3030

3131
()
3232

33+
[<Test>]
34+
member this.AllPairs() =
35+
// integer List
36+
let resultInt = List.allPairs [1..3] [2..2..6]
37+
Assert.AreEqual([(1,2);(1,4);(1,6)
38+
(2,2);(2,4);(2,6)
39+
(3,2);(3,4);(3,6)], resultInt)
40+
41+
// string List
42+
let resultStr = List.allPairs [2;3;4;5] ["b";"c";"d";"e"]
43+
Assert.AreEqual([(2,"b");(2,"c");(2,"d");(2,"e")
44+
(3,"b");(3,"c");(3,"d");(3,"e")
45+
(4,"b");(4,"c");(4,"d");(4,"e")
46+
(5,"b");(5,"c");(5,"d");(5,"e")] , resultStr)
47+
48+
// empty List
49+
let resultEpt = List.allPairs [] []
50+
let empTuple:(obj*obj) list = []
51+
Assert.AreEqual(empTuple, resultEpt)
52+
53+
()
54+
3355
[<Test>]
3456
member this.Append() =
3557
// integer List

src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListProperties.fs

+32
Original file line numberDiff line numberDiff line change
@@ -823,3 +823,35 @@ let ``List.sumBy calculates the sum of the mapped list`` () =
823823
Check.QuickThrowOnFailure sumBy<int>
824824
Check.QuickThrowOnFailure sumBy<string>
825825
Check.QuickThrowOnFailure sumBy<float>
826+
827+
let allPairsCount<'a, 'b> (xs : 'a list) (ys : 'b list) =
828+
let pairs = List.allPairs xs ys
829+
pairs.Length = xs.Length * ys.Length
830+
831+
[<Test>]
832+
let ``List.allPairs produces the correct number of pairs`` () =
833+
Check.QuickThrowOnFailure allPairsCount<int, int>
834+
Check.QuickThrowOnFailure allPairsCount<string, string>
835+
Check.QuickThrowOnFailure allPairsCount<float, float>
836+
837+
let allPairsFst<'a, 'b when 'a : equality> (xs : 'a list) (ys : 'b list) =
838+
let pairsFst = List.allPairs xs ys |> List.map fst
839+
let check = xs |> List.collect (List.replicate ys.Length)
840+
pairsFst = check
841+
842+
[<Test>]
843+
let ``List.allPairs first elements are correct`` () =
844+
Check.QuickThrowOnFailure allPairsFst<int, int>
845+
Check.QuickThrowOnFailure allPairsFst<string, string>
846+
Check.QuickThrowOnFailure allPairsFst<NormalFloat, NormalFloat>
847+
848+
let allPairsSnd<'a, 'b when 'b : equality> (xs : 'a list) (ys : 'b list) =
849+
let pairsSnd = List.allPairs xs ys |> List.map snd
850+
let check = [ for i in 1 .. xs.Length do yield! ys ]
851+
pairsSnd = check
852+
853+
[<Test>]
854+
let ``List.allPairs second elements are correct`` () =
855+
Check.QuickThrowOnFailure allPairsFst<int, int>
856+
Check.QuickThrowOnFailure allPairsFst<string, string>
857+
Check.QuickThrowOnFailure allPairsFst<NormalFloat, NormalFloat>

src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule.fs

+27
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,33 @@ Make sure each method works on:
2222
[<TestFixture>]
2323
type SeqModule() =
2424

25+
[<Test>]
26+
member this.AllPairs() =
27+
28+
// integer Seq
29+
let resultInt = Seq.allPairs (seq [1..7]) (seq [11..17])
30+
let expectedInt =
31+
seq { for i in 1..7 do
32+
for j in 11..17 do
33+
yield i, j }
34+
VerifySeqsEqual expectedInt resultInt
35+
36+
// string Seq
37+
let resultStr = Seq.allPairs (seq ["str3";"str4"]) (seq ["str1";"str2"])
38+
let expectedStr = seq ["str3","str1";"str3","str2";"str4","str1";"str4","str2"]
39+
VerifySeqsEqual expectedStr resultStr
40+
41+
// empty Seq
42+
VerifySeqsEqual Seq.empty <| Seq.allPairs Seq.empty Seq.empty
43+
VerifySeqsEqual Seq.empty <| Seq.allPairs { 1..7 } Seq.empty
44+
VerifySeqsEqual Seq.empty <| Seq.allPairs Seq.empty { 1..7 }
45+
46+
// null Seq
47+
CheckThrowsArgumentNullException(fun() -> Seq.allPairs null null |> ignore)
48+
CheckThrowsArgumentNullException(fun() -> Seq.allPairs null (seq [1..7]) |> ignore)
49+
CheckThrowsArgumentNullException(fun() -> Seq.allPairs (seq [1..7]) null |> ignore)
50+
()
51+
2552
[<Test>]
2653
member this.CachedSeq_Clear() =
2754

src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs

+3
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ Microsoft.FSharp.Collections.ArrayModule: System.Collections.Generic.IEnumerable
100100
Microsoft.FSharp.Collections.ArrayModule: System.String ToString()
101101
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[System.Int32,T][] Indexed[T](T[])
102102
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[])
103+
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] AllPairs[T1,T2](T1[], T2[])
103104
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
104105
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][])
105106
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
@@ -296,6 +297,7 @@ Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList
296297
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Windowed[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T])
297298
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Int32,T]] Indexed[T](Microsoft.FSharp.Collections.FSharpList`1[T])
298299
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T])
300+
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
299301
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
300302
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
301303
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
@@ -432,6 +434,7 @@ Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T]
432434
Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](System.Collections.Generic.IEnumerable`1[T])
433435
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.Int32,T]] Indexed[T](System.Collections.Generic.IEnumerable`1[T])
434436
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T,T]] Pairwise[T](System.Collections.Generic.IEnumerable`1[T])
437+
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2])
435438
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] Zip[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2])
436439
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Collections.Generic.IEnumerable`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T])
437440
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T])

src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs

+3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Microsoft.FSharp.Collections.ArrayModule: System.Collections.Generic.IEnumerable
8787
Microsoft.FSharp.Collections.ArrayModule: System.String ToString()
8888
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[System.Int32,T][] Indexed[T](T[])
8989
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[])
90+
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] AllPairs[T1,T2](T1[], T2[])
9091
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
9192
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][])
9293
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
@@ -283,6 +284,7 @@ Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList
283284
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Windowed[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T])
284285
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Int32,T]] Indexed[T](Microsoft.FSharp.Collections.FSharpList`1[T])
285286
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T])
287+
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
286288
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
287289
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
288290
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
@@ -419,6 +421,7 @@ Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T]
419421
Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](System.Collections.Generic.IEnumerable`1[T])
420422
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.Int32,T]] Indexed[T](System.Collections.Generic.IEnumerable`1[T])
421423
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T,T]] Pairwise[T](System.Collections.Generic.IEnumerable`1[T])
424+
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2])
422425
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] Zip[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2])
423426
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Collections.Generic.IEnumerable`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T])
424427
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T])

src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Microsoft.FSharp.Collections.ArrayModule: System.Collections.Generic.IEnumerable
8484
Microsoft.FSharp.Collections.ArrayModule: System.String ToString()
8585
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[System.Int32,T][] Indexed[T](T[])
8686
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[])
87+
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] AllPairs[T1,T2](T1[], T2[])
8788
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
8889
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][])
8990
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
@@ -280,6 +281,7 @@ Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList
280281
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Windowed[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T])
281282
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Int32,T]] Indexed[T](Microsoft.FSharp.Collections.FSharpList`1[T])
282283
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T])
284+
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
283285
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
284286
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
285287
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
@@ -416,6 +418,7 @@ Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T]
416418
Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](System.Collections.Generic.IEnumerable`1[T])
417419
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.Int32,T]] Indexed[T](System.Collections.Generic.IEnumerable`1[T])
418420
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T,T]] Pairwise[T](System.Collections.Generic.IEnumerable`1[T])
421+
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2])
419422
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] Zip[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2])
420423
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Collections.Generic.IEnumerable`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T])
421424
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T])

0 commit comments

Comments
 (0)