-
Notifications
You must be signed in to change notification settings - Fork 104
V1.3 F# core 6 #513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V1.3 F# core 6 #513
Changes from all commits
6911a01
85f85f4
38f6bc7
9c62c5d
866c19d
c56866c
f46e867
8e68f4c
a3034b2
25be4e7
df0018a
9d42ccf
d3f91d6
1dd397b
a90ce3b
b7eed9d
5a88d53
50cc0b6
42ca414
794c730
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,8 @@ namespace FSharpPlus | |
| module Array = | ||
|
|
||
| open System | ||
| open FSharp.Core.CompilerServices | ||
| open FSharpPlus.Internals.Errors | ||
|
|
||
| /// <summary>Applies an array of functions to an array of values and concatenates them.</summary> | ||
| /// <param name="f">The array of functions.</param> | ||
|
|
@@ -18,13 +20,22 @@ module Array = | |
| /// </code> | ||
| /// </example> | ||
| let apply f x = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(x)) x | ||
| #endif | ||
|
|
||
| let lenf, lenx = Array.length f, Array.length x | ||
| Array.init (lenf * lenx) (fun i -> f.[i / lenx] x.[i % lenx]) | ||
| Array.init (lenf * lenx) (fun i -> let (d, r) = Math.DivRem (i, lenx) in f.[d] x.[r]) | ||
|
|
||
| /// Combines all values from the first array with the second, using the supplied mapping function. | ||
| let lift2 f x y = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(x)) x | ||
| raiseIfNull (nameof(y)) y | ||
| #endif | ||
|
|
||
| let lenx, leny = Array.length x, Array.length y | ||
| Array.init (lenx * leny) (fun i -> f x.[i / leny] y.[i % leny]) | ||
| Array.init (lenx * leny) (fun i -> let (d, r) = Math.DivRem (i, leny) in f x.[d] y.[r]) | ||
|
|
||
|
|
||
| /// <summary>Combines all values from three arrays and calls a mapping function on this combination.</summary> | ||
|
|
@@ -35,23 +46,114 @@ module Array = | |
| /// | ||
| /// <returns>Array with values returned from mapping function.</returns> | ||
| let lift3 mapping list1 list2 list3 = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(list1)) list1 | ||
| raiseIfNull (nameof(list2)) list2 | ||
| raiseIfNull (nameof(list3)) list3 | ||
| #endif | ||
|
|
||
| let lenx, leny, lenz = Array.length list1, Array.length list2, Array.length list3 | ||
| let combinedFirstTwo = Array.init (lenx * leny) (fun i -> (list1.[i / leny], list2.[i % leny])) | ||
| let combinedFirstTwo = Array.init (lenx * leny) (fun i -> let (d, r) = Math.DivRem (i, leny) in (list1.[d], list2.[r])) | ||
|
|
||
| Array.init (lenx * leny * lenz) (fun i -> combinedFirstTwo.[i/leny], list3.[i%leny]) | ||
| Array.init (lenx * leny * lenz) (fun i -> let (d, r) = Math.DivRem (i, leny) in combinedFirstTwo.[d], list3.[r]) | ||
| |> Array.map (fun x -> mapping (fst (fst x)) (snd (fst x)) (snd x)) | ||
|
|
||
| /// Concatenates all elements, using the specified separator between each element. | ||
| let intercalate (separator: _ []) (source: seq<_ []>) = source |> Seq.intercalate separator |> Seq.toArray | ||
| let intercalate (separator: 'T []) (source: seq<'T []>) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
| #if FABLE_COMPILER || NET45 | ||
| source |> Seq.intercalate separator |> Seq.toArray | ||
| #else | ||
| let mutable coll = new ArrayCollector<'T> () | ||
| let mutable notFirst = false | ||
| source |> Seq.iter (fun element -> | ||
| if notFirst then coll.AddMany separator | ||
| coll.AddMany element | ||
| notFirst <- true) | ||
| coll.Close () | ||
| #endif | ||
|
|
||
| /// Inserts a separator element between each element in the source array. | ||
| let intersperse element source = source |> Array.toSeq |> Seq.intersperse element |> Seq.toArray : 'T [] | ||
| let intersperse element (source: 'T []) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
|
|
||
| match source with | ||
| | [||] -> [||] | ||
| | _ -> | ||
| let finalLength = Array.length source * 2 - 1 | ||
| Array.init finalLength (fun i -> | ||
| match Math.DivRem (i, 2) with | ||
| | i, 0 -> source.[i] | ||
| | _ -> element) | ||
|
|
||
| /// Creates a sequence of arrays by splitting the source array on any of the given separators. | ||
| let split (separators: seq<_ []>) (source: _ []) = source |> Array.toSeq |> Seq.split separators |> Seq.map Seq.toArray | ||
| let split (separators: seq<_ []>) (source: _ []) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(separators)) separators | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
|
|
||
| source |> Array.toSeq |> Seq.split separators |> Seq.map Seq.toArray | ||
|
|
||
| /// Replaces a subsequence of the source array with the given replacement array. | ||
| let replace oldValue newValue source = source |> Array.toSeq |> Seq.replace oldValue newValue |> Seq.toArray : 'T [] | ||
| let replace (oldValue: 'T seq) (newValue: 'T seq) (source: 'T[]) : 'T[] = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(oldValue)) oldValue | ||
| raiseIfNull (nameof(newValue)) newValue | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
| #if FABLE_COMPILER || NET45 | ||
| source |> Array.toSeq |> Seq.replace oldValue newValue |> Seq.toArray: 'T [] | ||
| #else | ||
| let oldValueArray = oldValue |> Seq.toArray | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to change to toArray here since the actual type signature in the released version of F#+ is seq as can be seen for instance here: |
||
| let newValueArray = newValue |> Seq.toArray | ||
| match source with | ||
| | [||] -> [||] | ||
| | _ -> | ||
| let mutable candidate = new ArrayCollector<'T>() | ||
| let mutable sourceIndex = 0 | ||
|
|
||
| while sourceIndex < source.Length do | ||
| let sourceItem = source.[sourceIndex] | ||
|
|
||
| if sourceItem = oldValueArray.[0] | ||
| && sourceIndex + newValueArray.Length <= source.Length then | ||
| let middleIndex = (oldValueArray.Length - 1) / 2 | ||
| let mutable oldValueIndexLeft = 0 | ||
|
|
||
| let mutable oldValueIndexRight = | ||
| oldValueArray.Length - 1 | ||
|
|
||
| let mutable matchingElements = | ||
| source.[sourceIndex + oldValueIndexLeft] = oldValueArray.[oldValueIndexLeft] | ||
| && source.[sourceIndex + oldValueIndexRight] = oldValueArray.[oldValueIndexRight] | ||
|
|
||
| while oldValueIndexLeft <= middleIndex | ||
| && oldValueIndexRight >= middleIndex | ||
| && matchingElements do | ||
| matchingElements <- | ||
| source.[sourceIndex + oldValueIndexLeft] = oldValueArray.[oldValueIndexLeft] | ||
| && source.[sourceIndex + oldValueIndexRight] = oldValueArray.[oldValueIndexRight] | ||
|
|
||
| oldValueIndexLeft <- oldValueIndexLeft + 1 | ||
| oldValueIndexRight <- oldValueIndexRight - 1 | ||
|
|
||
| if matchingElements then | ||
| candidate.AddMany newValueArray | ||
| sourceIndex <- sourceIndex + oldValueArray.Length | ||
| else | ||
| candidate.Add sourceItem | ||
| sourceIndex <- sourceIndex + 1 | ||
| else | ||
| sourceIndex <- sourceIndex + 1 | ||
| candidate.Add sourceItem | ||
|
|
||
| candidate.Close() | ||
| #endif | ||
|
|
||
| /// <summary> | ||
| /// Returns the index of the first occurrence of the specified slice in the source. | ||
|
|
@@ -72,6 +174,11 @@ module Array = | |
| /// The index of the slice or <c>None</c>. | ||
| /// </returns> | ||
| let findSliceIndex (slice: _ []) (source: _ []) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(slice)) slice | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
|
|
||
| let index = Internals.FindSliceIndex.arrayImpl slice source | ||
| if index = -1 then | ||
| ArgumentException("The specified slice was not found in the sequence.") |> raise | ||
|
|
@@ -86,6 +193,11 @@ module Array = | |
| /// The index of the slice or <c>None</c>. | ||
| /// </returns> | ||
| let tryFindSliceIndex (slice: _ []) (source: _ []) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(slice)) slice | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
|
|
||
| let index = Internals.FindSliceIndex.arrayImpl slice source | ||
| if index = -1 then None else Some index | ||
| #endif | ||
|
|
@@ -98,6 +210,10 @@ module Array = | |
| /// A tuple with both resulting arrays. | ||
| /// </returns> | ||
| let partitionMap (mapper: 'T -> Choice<'T1,'T2>) (source: array<'T>) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
|
|
||
| let (x, y) = ResizeArray (), ResizeArray () | ||
| Array.iter (mapper >> function Choice1Of2 e -> x.Add e | Choice2Of2 e -> y.Add e) source | ||
| x.ToArray (), y.ToArray () | ||
|
|
@@ -106,6 +222,11 @@ module Array = | |
| /// to each of the elements of the two arrays pairwise.</summary> | ||
| /// <remark>If one array is shorter, excess elements are discarded from the right end of the longer array.</remark> | ||
| let map2Shortest f (a1: 'T []) (a2: 'U []) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(a1)) a1 | ||
| raiseIfNull (nameof(a2)) a2 | ||
| #endif | ||
|
|
||
| Array.init (min a1.Length a2.Length) (fun i -> f a1.[i] a2.[i]) | ||
|
|
||
| /// <summary> | ||
|
|
@@ -115,6 +236,11 @@ module Array = | |
| /// <param name="a2">Second input array.</param> | ||
| /// <returns>Array with corresponding pairs of input arrays.</returns> | ||
| let zipShortest (a1: array<'T1>) (a2: array<'T2>) = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(a1)) a1 | ||
| raiseIfNull (nameof(a2)) a2 | ||
| #endif | ||
|
|
||
| Array.init (min a1.Length a2.Length) (fun i -> a1.[i], a2.[i]) | ||
|
|
||
| /// <summary>Same as choose but with access to the index.</summary> | ||
|
|
@@ -123,6 +249,10 @@ module Array = | |
| /// | ||
| /// <returns>Array with values x for each Array value where the function returns Some(x).</returns> | ||
| let choosei mapping source = | ||
| #if !NET45 | ||
| raiseIfNull (nameof(source)) source | ||
| #endif | ||
|
|
||
| let mutable i = ref -1 | ||
| let fi x = | ||
| i.Value <- i.Value + 1 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that both net45 and Fable lack ListCollector @gusty