Skip to content

Commit

Permalink
Merge pull request #513 from fsprojects/v1.3-fsharp-core-6
Browse files Browse the repository at this point in the history
V1.3 F# core 6
  • Loading branch information
wallymathieu authored Nov 13, 2022
2 parents 4b4f5dd + 794c730 commit 732390f
Show file tree
Hide file tree
Showing 34 changed files with 1,415 additions and 766 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ Please do join us to chat on:

- Gitter
[![Join the chat at https://gitter.im/fsprojects/FSharpPlus](https://badges.gitter.im/fsprojects/FSharpPlus.svg)](https://gitter.im/fsprojects/FSharpPlus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- [#FSharpPlus on Functional programming Slack](https://app.slack.com/client/T0432GV8P/CTT70ER47)
If you need to request an invitation head to https://fpchat-invite.herokuapp.com/ to get one.
- You can get invited into the [functional programming Slack](https://app.slack.com/client/T0432GV8P/CTT70ER47) and then join [#FSharpPlus](https://functionalprogramming.slack.com/join/shared_invite/zt-svowkzcg-6xzAuVrUtINX7swWuhjHUw#/shared-invite/email)

...or you can [ask a question on stack overflow](https://stackoverflow.com/questions/ask?tags=f%23%2b)
with tag `F#+`
Expand Down
2 changes: 1 addition & 1 deletion build.proj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<Target Name="Test">
<Exec Command='dotnet build src/FSharpPlus.TypeLevel' WorkingDirectory="$(RepoRootDir)" IgnoreStandardErrorWarningFormat="true" />
<Exec Command='dotnet test tests/FSharpPlus.Tests -c Release --logger:trx' WorkingDirectory="$(RepoRootDir)" IgnoreStandardErrorWarningFormat="true" />
<Exec Command='dotnet test --blame-hang-timeout 30s tests/FSharpPlus.Tests -c Release --logger:trx' WorkingDirectory="$(RepoRootDir)" IgnoreStandardErrorWarningFormat="true" />
</Target>

<!-- dotnet msbuild -target:AllDocs build.proj -->
Expand Down
3 changes: 2 additions & 1 deletion docsrc/content/extensions.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,11 @@ Collections / Traversable types:
Async and Tasks:
================
* [ Task ](reference/fsharpplus-task.html)
* map, map2
* map, map2, map3
* apply
* zip
* join
* ignore
* [ Async ](reference/fsharpplus-async.html)
* map, map2
* zip
Expand Down
3 changes: 2 additions & 1 deletion docsrc/content/tutorial.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// This block of code is omitted in the generated HTML documentation. Use
// it to define helpers that you do not want to show in the documentation.

#r @"../../src/FSharpPlus/bin/Release/net45/FSharpPlus.dll"
#r @"../../src/FSharpPlus/bin/Release/netstandard2.0/FSharpPlus.dll"
#nowarn "0058" // We need to cheat a bit with indentation here.

(**
Introducing FSharpPlus
Expand Down
2 changes: 1 addition & 1 deletion docsrc/tools/docsTool.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/FSharpPlus.Docs/FSharpPlus.Docs.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\FSharpPlus\FSharpPlus.fsproj" />
<ProjectReference Include="..\..\src\FSharpPlus.TypeLevel\FSharpPlus.TypeLevel.fsproj" />
<PackageReference Update="FSharp.Core" Version="4.6.2" />
<PackageReference Update="FSharp.Core" Version="6.0.6" />
<PackageReference Include="MathNet.Numerics.FSharp" Version="4.8.1" />
</ItemGroup>
</Project>
3 changes: 2 additions & 1 deletion src/FSharpPlus.TypeLevel/FSharpPlus.TypeLevel.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
<Compile Include="Providers/TypeProviderAssembly.fs" />-->
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="4.6.2" />
<PackageReference Update="FSharp.Core" Version="4.6.2" Condition=" '$(TargetFramework)' == 'net45'" />
<PackageReference Update="FSharp.Core" Version="6.0.6" Condition=" '$(TargetFramework)' != 'net45'" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../FSharpPlus/FSharpPlus.fsproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
<Reference Condition=" '$(TargetFramework)' == 'net45'" Include="System.Runtime" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="4.6.2" />
<PackageReference Update="FSharp.Core" Version="4.6.2" Condition=" '$(TargetFramework)' == 'net45'" />
<PackageReference Update="FSharp.Core" Version="6.0.6" Condition=" '$(TargetFramework)' != 'net45'" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../FSharpPlus.TypeLevel.fsproj" />
Expand Down
165 changes: 123 additions & 42 deletions src/FSharpPlus/Builders.fs

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/FSharpPlus/Control/Functor.fs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ type Unzip =
#endif

static member Unzip ((source: Async<'T * 'U> , _output: Async<'T> * Async<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
static member Unzip ((source: Result<'T * 'U, 'E> , _output: Result<'T,'E> * Result<'U,'E> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
static member Unzip ((source: Result<'T * 'U, 'E> , _output: Result<'T,'E> * Result<'U,'E> ) , _mthd: Unzip ) = Result.unzip source
static member Unzip ((source: Choice<'T * 'U, 'E> , _output: Choice<'T,'E> * Choice<'U,'E> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
static member Unzip ((source: KeyValuePair<'Key, 'T * 'U> , _output: KeyValuePair<_, 'T> * KeyValuePair<_, 'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
static member Unzip ((source: Map<'Key, 'T * 'U> , _output: Map<_, 'T> * Map<_, 'U> ) , _mthd: Unzip ) = Map.unzip source
Expand Down Expand Up @@ -205,6 +205,7 @@ type Zip =
static member Zip ((x: 'T [] , y: 'U [] , _output: ('T*'U) [] ), _mthd: Zip) = Array.zipShortest x y
static member Zip ((x: ResizeArray<'T> , y: ResizeArray<'U> , _output: ResizeArray<'T*'U> ), _mthd: Zip) = ResizeArray.zipShortest x y
static member Zip ((x: option<'T> , y: option<'U> , _output: option<'T*'U> ), _mthd: Zip) = Option.zip x y
static member Zip ((x: Result<'T, 'Error> , y: Result<'U, 'Error> , _output: Result<'T * 'U, 'Error> ), _mthd: Zip) = Result.zip x y
static member Zip ((x: Async<'T> , y: Async<'U> , _output: Async<'T*'U> ), _mthd: Zip) = Async.zip x y
#if !FABLE_COMPILER
static member Zip ((x: Task<'T> , y: Task<'U> , _output: Task<'T*'U> ), _mthd: Zip) = Task.zip x y
Expand Down
8 changes: 8 additions & 0 deletions src/FSharpPlus/Data/Validation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Validation<'error, 't> =
| Success of 't

module Validation =
open FSharp.Core.CompilerServices

let map (f: 'T->'U) (source: Validation<'Error,'T>) =
match source with
Expand Down Expand Up @@ -228,13 +229,20 @@ module Validation =
/// A tuple with both resulting lists, Success are in the first list.
/// </returns>
let partition (source: list<Validation<'TErrors, 'T>>) =
#if FABLE_COMPILER || NET45
let rec loop ((acc1, acc2) as acc) = function
| [] -> acc
| x::xs ->
match x with
| Success x -> loop (x::acc1, acc2) xs
| Failure x -> loop (acc1, x::acc2) xs
loop ([], []) (List.rev source)
#else
let mutable coll1 = new ListCollector<'T> ()
let mutable coll2 = new ListCollector<'TErrors> ()
List.iter (function Success e -> coll1.Add e | Failure e -> coll2.Add e) source
coll1.Close (), coll2.Close ()
#endif


type Validation<'err,'a> with
Expand Down
146 changes: 138 additions & 8 deletions src/FSharpPlus/Extensions/Array.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand All @@ -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
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.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 ()
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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
Expand Down
12 changes: 11 additions & 1 deletion src/FSharpPlus/Extensions/Extensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module Extensions =

open System.Threading
open System.Threading.Tasks
open FSharp.Core.CompilerServices

let private (|Canceled|Faulted|Completed|) (t: Task<'a>) =
if t.IsCanceled then Canceled
Expand Down Expand Up @@ -74,11 +75,20 @@ module Extensions =
#endif

/// Combine all asyncs in one, chaining them in sequence order.
static member Sequence (t: list<Async<_>>) : Async<list<_>> =
static member Sequence (t: list<Async<'T>>) : Async<list<'T>> =
#if FABLE_COMPILER || NET45
let rec loop acc = function
| [] -> async.Return (List.rev acc)
| x::xs -> async.Bind (x, fun x -> loop (x::acc) xs)
loop [] t
#else
async {
let mutable coll = ListCollector<'T> ()
for e in t do
let! v = e
coll.Add v
return coll.Close () }
#endif

/// Combine all asyncs in one, chaining them in sequence order.
static member Sequence (t: array<Async<_>>) : Async<array<_>> = async {
Expand Down
Loading

0 comments on commit 732390f

Please sign in to comment.