Skip to content

Commit 173d833

Browse files
forkilatkin
authored andcommitted
Implement Array.replicate, Seq.replicate
Commits: Create missing test for List.replicate Implement Array.replicate Implement Seq.replicate Make the docs for replicate a bit clearer Use only one test method for replicate Test for negative arguments for replicate Variable i not used in Seq.replicate Use mutable cons cell for List.replicate Use System.Linq.Enumerable.Repeat in Seq.replicate if we are on .NET 4.0 or higher Adding surface area for replicate Small tweaks Rolling back change to List.replicate
1 parent b10392d commit 173d833

10 files changed

Lines changed: 67 additions & 2 deletions

File tree

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,16 @@ type ArrayModule() =
239239

240240
CheckThrowsArgumentNullException (fun () -> Array.splitAt 0 null |> ignore)
241241
CheckThrowsArgumentNullException (fun () -> Array.splitAt 1 null |> ignore)
242+
243+
[<Test>]
244+
member this.replicate() =
245+
// replicate should create multiple copies of the given value
246+
Assert.AreEqual([||],Array.replicate 0 null)
247+
Assert.AreEqual([||],Array.replicate 0 1)
248+
Assert.AreEqual([|null|],Array.replicate 1 null)
249+
Assert.AreEqual([|"1";"1"|],Array.replicate 2 "1")
250+
251+
CheckThrowsArgumentException (fun () -> Array.replicate -1 null |> ignore)
242252

243253
[<Test>]
244254
member this.Blit() =

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,16 @@ type ListModule() =
378378

379379
()
380380

381+
[<Test>]
382+
member this.replicate() =
383+
// replicate should create multiple copies of the given value
384+
Assert.AreEqual([],List.replicate 0 null)
385+
Assert.AreEqual([],List.replicate 0 1)
386+
Assert.AreEqual([null],List.replicate 1 null)
387+
Assert.AreEqual(["1";"1"],List.replicate 2 "1")
388+
389+
CheckThrowsArgumentException (fun () -> List.replicate -1 null |> ignore)
390+
381391
[<Test>]
382392
member this.FindIndex() =
383393
// integer List

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ type SeqModule() =
106106
VerifySeqsEqual expectedResultNull appendNullSeq
107107

108108
()
109+
110+
[<Test>]
111+
member this.replicate() =
112+
// replicate should create multiple copies of the given value
113+
Assert.IsTrue(Seq.isEmpty <| Seq.replicate 0 null)
114+
Assert.IsTrue(Seq.isEmpty <| Seq.replicate 0 1)
115+
Assert.AreEqual(null, Seq.head <| Seq.replicate 1 null)
116+
Assert.AreEqual(["1";"1"],Seq.replicate 2 "1" |> Seq.toList)
117+
118+
CheckThrowsArgumentException (fun () -> Seq.replicate -1 null |> ignore)
109119

110120

111121
[<Test>]

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ Microsoft.FSharp.Collections.ArrayModule: T[] Initialize[T](Int32, Microsoft.FSh
160160
Microsoft.FSharp.Collections.ArrayModule: T[] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T])
161161
Microsoft.FSharp.Collections.ArrayModule: T[] OfSeq[T](System.Collections.Generic.IEnumerable`1[T])
162162
Microsoft.FSharp.Collections.ArrayModule: T[] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], T[])
163+
Microsoft.FSharp.Collections.ArrayModule: T[] Replicate[T](Int32, T)
163164
Microsoft.FSharp.Collections.ArrayModule: T[] Reverse[T](T[])
164165
Microsoft.FSharp.Collections.ArrayModule: T[] Singleton[T](T)
165166
Microsoft.FSharp.Collections.ArrayModule: T[] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
@@ -419,6 +420,7 @@ Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1
419420
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfArray[T](T[])
420421
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T])
421422
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] ReadOnly[T](System.Collections.Generic.IEnumerable`1[T])
423+
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Replicate[T](Int32, T)
422424
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Singleton[T](T)
423425
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T])
424426
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Skip[T](Int32, System.Collections.Generic.IEnumerable`1[T])

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ Microsoft.FSharp.Collections.ArrayModule: T[] Initialize[T](Int32, Microsoft.FSh
154154
Microsoft.FSharp.Collections.ArrayModule: T[] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T])
155155
Microsoft.FSharp.Collections.ArrayModule: T[] OfSeq[T](System.Collections.Generic.IEnumerable`1[T])
156156
Microsoft.FSharp.Collections.ArrayModule: T[] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], T[])
157+
Microsoft.FSharp.Collections.ArrayModule: T[] Replicate[T](Int32, T)
157158
Microsoft.FSharp.Collections.ArrayModule: T[] Reverse[T](T[])
158159
Microsoft.FSharp.Collections.ArrayModule: T[] Singleton[T](T)
159160
Microsoft.FSharp.Collections.ArrayModule: T[] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
@@ -413,6 +414,7 @@ Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1
413414
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfArray[T](T[])
414415
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T])
415416
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] ReadOnly[T](System.Collections.Generic.IEnumerable`1[T])
417+
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Replicate[T](Int32, T)
416418
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Singleton[T](T)
417419
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T])
418420
Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Skip[T](Int32, System.Collections.Generic.IEnumerable`1[T])

src/fsharp/FSharp.Core/array.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ namespace Microsoft.FSharp.Collections
102102
match arrays with
103103
| :? ('T[][]) as ts -> ts |> concatArrays // avoid a clone, since we only read the array
104104
| _ -> arrays |> Seq.toArray |> concatArrays
105+
106+
[<CompiledName("Replicate")>]
107+
let replicate count x =
108+
if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative))
109+
let arr = (Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked count : 'T array)
110+
for i = 0 to count - 1 do
111+
arr.[i] <- x
112+
arr
105113

106114
[<CompiledName("Collect")>]
107115
let collect (f : 'T -> 'U[]) (array : 'T[]) : 'U[]=

src/fsharp/FSharp.Core/array.fsi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,13 @@ namespace Microsoft.FSharp.Collections
530530
[<CompiledName("ReduceBack")>]
531531
val reduceBack: reduction:('T -> 'T -> 'T) -> array:'T[] -> 'T
532532

533+
/// <summary>Creates an array by replicating the given initial value.</summary>
534+
/// <param name="count">The number of elements to replicate.</param>
535+
/// <param name="initial">The value to replicate</param>
536+
/// <returns>The generated array.</returns>
537+
[<CompiledName("Replicate")>]
538+
val replicate: count:int -> initial:'T -> 'T[]
539+
533540
/// <summary>Returns a new array with the elements in reverse order.</summary>
534541
/// <param name="array">The input array.</param>
535542
/// <returns>The reversed array.</returns>

src/fsharp/FSharp.Core/list.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ namespace Microsoft.FSharp.Collections
480480
[<CompiledName("ReduceBack")>]
481481
val reduceBack: reduction:('T -> 'T -> 'T) -> list:'T list -> 'T
482482

483-
/// <summary>Creates a list by calling the given generator on each index.</summary>
483+
/// <summary>Creates a list by replicating the given initial value.</summary>
484484
/// <param name="count">The number of elements to replicate.</param>
485485
/// <param name="initial">The value to replicate</param>
486486
/// <returns>The generated list.</returns>

src/fsharp/FSharp.Core/seq.fs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,16 @@ namespace Microsoft.FSharp.Collections
10591059

10601060
let fromGenerator f = mkSeq(fun () -> Generator.EnumerateFromGenerator (f()))
10611061
let toGenerator (ie : seq<_>) = Generator.GenerateFromEnumerator (ie.GetEnumerator())
1062-
1062+
1063+
[<CompiledName("Replicate")>]
1064+
let replicate count x =
1065+
#if FX_ATLEAST_40
1066+
System.Linq.Enumerable.Repeat(x,count)
1067+
#else
1068+
if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative))
1069+
seq { for _ in 1 .. count -> x }
1070+
#endif
1071+
10631072

10641073
[<CompiledName("Append")>]
10651074
let append (source1: seq<'T>) (source2: seq<'T>) =

src/fsharp/FSharp.Core/seq.fsi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,13 @@ namespace Microsoft.FSharp.Collections
721721
[<CompiledName("Reduce")>]
722722
val reduce: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T
723723

724+
/// <summary>Creates a sequence by replicating the given initial value.</summary>
725+
/// <param name="count">The number of elements to replicate.</param>
726+
/// <param name="initial">The value to replicate</param>
727+
/// <returns>The generated sequence.</returns>
728+
[<CompiledName("Replicate")>]
729+
val replicate: count:int -> initial:'T -> seq<'T>
730+
724731
/// <summary>Like fold, but computes on-demand and returns the sequence of intermediary and final results.</summary>
725732
///
726733
/// <param name="folder">A function that updates the state with each element from the sequence.</param>

0 commit comments

Comments
 (0)