Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/absil/illib.fs
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,10 @@ module List =
let existsSquared f xss = xss |> List.exists (fun xs -> xs |> List.exists (fun x -> f x))
let mapiFoldSquared f z xss = mapFoldSquared f z (xss |> mapiSquared (fun i j x -> (i,j,x)))

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module ValueOption =
/// Because FSharp.Compiler.Service is a library that will target FSharp.Core 4.5.2 for the forseeable future,
/// we need to stick these functions in this module rather than using the module functions for ValueOption
/// that come after FSharp.Core 4.5.2.
module ValueOptionInternal =
let inline ofOption x = match x with Some x -> ValueSome x | None -> ValueNone
let inline bind f x = match x with ValueSome x -> f x | ValueNone -> ValueNone
let inline isSome x = match x with ValueSome _ -> true | ValueNone -> false
Expand Down
4 changes: 2 additions & 2 deletions src/buildfromsource/FSharp.Compiler.Private/FSComp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3197,10 +3197,10 @@ type internal SR private() =
/// (Originally from ..\FSComp.txt:1044)
static member tastInvalidAddressOfMutableAcrossAssemblyBoundary() = (1188, GetStringFunc("tastInvalidAddressOfMutableAcrossAssemblyBoundary",",,,") )
/// Remove spaces between the type name and type parameter, e.g. \"type C<'T>\", not type \"C <'T>\". Type parameters must be placed directly adjacent to the type name.
/// (Originally from ..\FSComp.txt:1045)
/// (Originally from ..\FSComp.txt:1043)
static member parsNonAdjacentTypars() = (1189, GetStringFunc("parsNonAdjacentTypars",",,,") )
/// Remove spaces between the type name and type parameter, e.g. \"C<'T>\", not \"C <'T>\". Type parameters must be placed directly adjacent to the type name.
/// (Originally from ..\FSComp.txt:1046)
/// (Originally from ..\FSComp.txt:1044)
static member parsNonAdjacentTyargs() = (1190, GetStringFunc("parsNonAdjacentTyargs",",,,") )
/// The use of the type syntax 'int C' and 'C <int>' is not permitted here. Consider adjusting this type to be written in the form 'C<int>'
/// (Originally from ..\FSComp.txt:1047)
Expand Down
12 changes: 4 additions & 8 deletions src/fsharp/FSharp.Build/Microsoft.FSharp.NetSdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,10 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<Tailcalls Condition="'$(Tailcalls)' == '' ">true</Tailcalls>
</PropertyGroup>

<PropertyGroup Condition=" '$(OS)' != 'Unix' and Exists('$(MSBuildThisFileDirectory)\RunFsc.cmd')" >
<FscToolPath Condition=" '$(FscToolPath)' == '' ">$(MSBuildThisFileDirectory)</FscToolPath>
<FscToolExe Condition=" '$(FscToolExe)' == ''">RunFsc.cmd</FscToolExe>
</PropertyGroup>

<PropertyGroup Condition=" '$(OS)' == 'Unix' and Exists('$(MSBuildThisFileDirectory)\RunFsc.sh')" >
<FscToolPath Condition=" '$(FscToolPath)' == '' ">$(MSBuildThisFileDirectory)</FscToolPath>
<FscToolExe Condition="'$(OS)' == 'Unix' and '$(FscToolExe)' == ''">RunFsc.sh</FscToolExe>
<PropertyGroup Condition="'$(DOTNET_HOST_PATH)' != ''">
<FscToolPath Condition="'$(FscToolPath)' == ''">$([System.IO.Path]::GetDirectoryName($(DOTNET_HOST_PATH)))</FscToolPath>
<FscToolExe Condition="'$(FscToolExe)' == ''">$([System.IO.Path]::GetFileName($(DOTNET_HOST_PATH)))</FscToolExe>
<DotnetFscCompilerPath>"$(MSBuildThisFileDirectory)fsc.exe"</DotnetFscCompilerPath>
</PropertyGroup>

<ItemGroup Condition="'$(DisableImplicitSystemValueTupleReference)' != 'true'
Expand Down
6 changes: 6 additions & 0 deletions src/fsharp/FSharp.Core/array.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,12 @@ namespace Microsoft.FSharp.Collections
elif array.Length = 0 then invalidArg "array" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString
else invalidArg "array" (SR.GetString(SR.inputSequenceTooLong))

[<CompiledName("TryExactlyOne")>]
let tryExactlyOne (array:'T[]) =
checkNonNull "array" array
if array.Length = 1 then Some array.[0]
else None

let transposeArrays (array:'T[][]) =
let len = array.Length
if len = 0 then Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked 0 else
Expand Down
10 changes: 10 additions & 0 deletions src/fsharp/FSharp.Core/array.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ namespace Microsoft.FSharp.Collections
[<CompiledName("ExactlyOne")>]
val exactlyOne: array:'T[] -> 'T

/// <summary>Returns the only element of the array or <c>None</c> if array is empty or contains more than one element.</summary>
///
/// <param name="array">The input array.</param>
///
/// <returns>The only element of the array or None.</returns>
///
/// <exception cref="System.ArgumentNullException">Thrown when the input array is null.</exception>
[<CompiledName("TryExactlyOne")>]
val tryExactlyOne: array:'T[] -> 'T option

/// <summary>Returns a new list with the distinct elements of the input array which do not appear in the itemsToExclude sequence,
/// using generic hash and equality comparisons to compare values.</summary>
///
Expand Down
6 changes: 6 additions & 0 deletions src/fsharp/FSharp.Core/list.fs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,12 @@ namespace Microsoft.FSharp.Collections
| [] -> invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString
| _ -> invalidArg "source" (SR.GetString(SR.inputSequenceTooLong))

[<CompiledName("TryExactlyOne")>]
let tryExactlyOne (list : list<_>) =
match list with
| [x] -> Some x
| _ -> None

[<CompiledName("Transpose")>]
let transpose (lists : seq<'T list>) =
checkNonNull "lists" lists
Expand Down
8 changes: 8 additions & 0 deletions src/fsharp/FSharp.Core/list.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ namespace Microsoft.FSharp.Collections
[<CompiledName("ExactlyOne")>]
val exactlyOne: list:'T list -> 'T

/// <summary>Returns the only element of the list or <c>None</c> if it is empty or contains more than one element.</summary>
///
/// <param name="list">The input list.</param>
///
/// <returns>The only element of the list or None.</returns>
[<CompiledName("TryExactlyOne")>]
val tryExactlyOne: list:'T list -> 'T option

/// <summary>Tests if any element of the list satisfies the given predicate.</summary>
///
/// <remarks>The predicate is applied to the elements of the input list. If any application
Expand Down
208 changes: 147 additions & 61 deletions src/fsharp/FSharp.Core/option.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,91 +2,177 @@

namespace Microsoft.FSharp.Core

open Microsoft.FSharp.Core.Operators
open Microsoft.FSharp.Core.Operators

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Option =
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Option =

[<CompiledName("GetValue")>]
let get option = match option with None -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | Some x -> x
[<CompiledName("GetValue")>]
let get option = match option with None -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | Some x -> x

[<CompiledName("IsSome")>]
let inline isSome option = match option with None -> false | Some _ -> true
[<CompiledName("IsSome")>]
let inline isSome option = match option with None -> false | Some _ -> true

[<CompiledName("IsNone")>]
let inline isNone option = match option with None -> true | Some _ -> false
[<CompiledName("IsNone")>]
let inline isNone option = match option with None -> true | Some _ -> false

[<CompiledName("DefaultValue")>]
let defaultValue value option = match option with None -> value | Some v -> v
[<CompiledName("DefaultValue")>]
let defaultValue value option = match option with None -> value | Some v -> v

[<CompiledName("DefaultWith")>]
let defaultWith defThunk option = match option with None -> defThunk () | Some v -> v
[<CompiledName("DefaultWith")>]
let defaultWith defThunk option = match option with None -> defThunk () | Some v -> v

[<CompiledName("OrElse")>]
let orElse ifNone option = match option with None -> ifNone | Some _ -> option
[<CompiledName("OrElse")>]
let orElse ifNone option = match option with None -> ifNone | Some _ -> option

[<CompiledName("OrElseWith")>]
let orElseWith ifNoneThunk option = match option with None -> ifNoneThunk () | Some _ -> option
[<CompiledName("OrElseWith")>]
let orElseWith ifNoneThunk option = match option with None -> ifNoneThunk () | Some _ -> option

[<CompiledName("Count")>]
let count option = match option with None -> 0 | Some _ -> 1
[<CompiledName("Count")>]
let count option = match option with None -> 0 | Some _ -> 1

[<CompiledName("Fold")>]
let fold<'T,'State> folder (state:'State) (option: option<'T>) = match option with None -> state | Some x -> folder state x
[<CompiledName("Fold")>]
let fold<'T,'State> folder (state:'State) (option: option<'T>) = match option with None -> state | Some x -> folder state x

[<CompiledName("FoldBack")>]
let foldBack<'T,'State> folder (option: option<'T>) (state:'State) = match option with None -> state | Some x -> folder x state
[<CompiledName("FoldBack")>]
let foldBack<'T,'State> folder (option: option<'T>) (state:'State) = match option with None -> state | Some x -> folder x state

[<CompiledName("Exists")>]
let exists predicate option = match option with None -> false | Some x -> predicate x
[<CompiledName("Exists")>]
let exists predicate option = match option with None -> false | Some x -> predicate x

[<CompiledName("ForAll")>]
let forall predicate option = match option with None -> true | Some x -> predicate x
[<CompiledName("ForAll")>]
let forall predicate option = match option with None -> true | Some x -> predicate x

[<CompiledName("Contains")>]
let inline contains value option = match option with None -> false | Some v -> v = value
[<CompiledName("Contains")>]
let inline contains value option = match option with None -> false | Some v -> v = value

[<CompiledName("Iterate")>]
let iter action option = match option with None -> () | Some x -> action x
[<CompiledName("Iterate")>]
let iter action option = match option with None -> () | Some x -> action x

[<CompiledName("Map")>]
let map mapping option = match option with None -> None | Some x -> Some (mapping x)
[<CompiledName("Map")>]
let map mapping option = match option with None -> None | Some x -> Some (mapping x)

[<CompiledName("Map2")>]
let map2 mapping option1 option2 =
match option1, option2 with
| Some x, Some y -> Some (mapping x y)
| _ -> None
[<CompiledName("Map2")>]
let map2 mapping option1 option2 =
match option1, option2 with
| Some x, Some y -> Some (mapping x y)
| _ -> None

[<CompiledName("Map3")>]
let map3 mapping option1 option2 option3 =
match option1, option2, option3 with
| Some x, Some y, Some z -> Some (mapping x y z)
| _ -> None
[<CompiledName("Map3")>]
let map3 mapping option1 option2 option3 =
match option1, option2, option3 with
| Some x, Some y, Some z -> Some (mapping x y z)
| _ -> None

[<CompiledName("Bind")>]
let bind binder option = match option with None -> None | Some x -> binder x
[<CompiledName("Bind")>]
let bind binder option = match option with None -> None | Some x -> binder x

[<CompiledName("Flatten")>]
let flatten option = match option with None -> None | Some x -> x
[<CompiledName("Flatten")>]
let flatten option = match option with None -> None | Some x -> x

[<CompiledName("Filter")>]
let filter predicate option = match option with None -> None | Some x -> if predicate x then Some x else None
[<CompiledName("Filter")>]
let filter predicate option = match option with None -> None | Some x -> if predicate x then Some x else None

[<CompiledName("ToArray")>]
let toArray option = match option with None -> [| |] | Some x -> [| x |]
[<CompiledName("ToArray")>]
let toArray option = match option with None -> [| |] | Some x -> [| x |]

[<CompiledName("ToList")>]
let toList option = match option with None -> [ ] | Some x -> [ x ]
[<CompiledName("ToList")>]
let toList option = match option with None -> [ ] | Some x -> [ x ]

[<CompiledName("ToNullable")>]
let toNullable option = match option with None -> System.Nullable() | Some v -> System.Nullable(v)
[<CompiledName("ToNullable")>]
let toNullable option = match option with None -> System.Nullable() | Some v -> System.Nullable(v)

[<CompiledName("OfNullable")>]
let ofNullable (value:System.Nullable<'T>) = if value.HasValue then Some value.Value else None
[<CompiledName("OfNullable")>]
let ofNullable (value:System.Nullable<'T>) = if value.HasValue then Some value.Value else None

[<CompiledName("OfObj")>]
let ofObj value = match value with null -> None | _ -> Some value
[<CompiledName("OfObj")>]
let ofObj value = match value with null -> None | _ -> Some value

[<CompiledName("ToObj")>]
let toObj value = match value with None -> null | Some x -> x
[<CompiledName("ToObj")>]
let toObj value = match value with None -> null | Some x -> x

module ValueOption =

[<CompiledName("GetValue")>]
let get voption = match voption with ValueNone -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | ValueSome x -> x

[<CompiledName("IsSome")>]
let inline isSome voption = match voption with ValueNone -> false | ValueSome _ -> true

[<CompiledName("IsNone")>]
let inline isNone voption = match voption with ValueNone -> true | ValueSome _ -> false

[<CompiledName("DefaultValue")>]
let defaultValue value voption = match voption with ValueNone -> value | ValueSome v -> v

[<CompiledName("DefaultWith")>]
let defaultWith defThunk voption = match voption with ValueNone -> defThunk () | ValueSome v -> v

[<CompiledName("OrElse")>]
let orElse ifNone voption = match voption with ValueNone -> ifNone | ValueSome _ -> voption

[<CompiledName("OrElseWith")>]
let orElseWith ifNoneThunk voption = match voption with ValueNone -> ifNoneThunk () | ValueSome _ -> voption

[<CompiledName("Count")>]
let count voption = match voption with ValueNone -> 0 | ValueSome _ -> 1

[<CompiledName("Fold")>]
let fold<'T,'State> folder (state:'State) (voption: voption<'T>) = match voption with ValueNone -> state | ValueSome x -> folder state x

[<CompiledName("FoldBack")>]
let foldBack<'T,'State> folder (voption: voption<'T>) (state:'State) = match voption with ValueNone -> state | ValueSome x -> folder x state

[<CompiledName("Exists")>]
let exists predicate voption = match voption with ValueNone -> false | ValueSome x -> predicate x

[<CompiledName("ForAll")>]
let forall predicate voption = match voption with ValueNone -> true | ValueSome x -> predicate x

[<CompiledName("Contains")>]
let inline contains value voption = match voption with ValueNone -> false | ValueSome v -> v = value

[<CompiledName("Iterate")>]
let iter action voption = match voption with ValueNone -> () | ValueSome x -> action x

[<CompiledName("Map")>]
let map mapping voption = match voption with ValueNone -> ValueNone | ValueSome x -> ValueSome (mapping x)

[<CompiledName("Map2")>]
let map2 mapping voption1 voption2 =
match voption1, voption2 with
| ValueSome x, ValueSome y -> ValueSome (mapping x y)
| _ -> ValueNone

[<CompiledName("Map3")>]
let map3 mapping voption1 voption2 voption3 =
match voption1, voption2, voption3 with
| ValueSome x, ValueSome y, ValueSome z -> ValueSome (mapping x y z)
| _ -> ValueNone

[<CompiledName("Bind")>]
let bind binder voption = match voption with ValueNone -> ValueNone | ValueSome x -> binder x

[<CompiledName("Flatten")>]
let flatten voption = match voption with ValueNone -> ValueNone | ValueSome x -> x

[<CompiledName("Filter")>]
let filter predicate voption = match voption with ValueNone -> ValueNone | ValueSome x -> if predicate x then ValueSome x else ValueNone

[<CompiledName("ToArray")>]
let toArray voption = match voption with ValueNone -> [| |] | ValueSome x -> [| x |]

[<CompiledName("ToList")>]
let toList voption = match voption with ValueNone -> [ ] | ValueSome x -> [ x ]

[<CompiledName("ToNullable")>]
let toNullable voption = match voption with ValueNone -> System.Nullable() | ValueSome v -> System.Nullable(v)

[<CompiledName("OfNullable")>]
let ofNullable (value:System.Nullable<'T>) = if value.HasValue then ValueSome value.Value else ValueNone

[<CompiledName("OfObj")>]
let ofObj value = match value with null -> ValueNone | _ -> ValueSome value

[<CompiledName("ToObj")>]
let toObj value = match value with ValueNone -> null | ValueSome x -> x
Loading