From f2b8f3569964bfc143e3ee9bb6e3f919580b60a3 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Fri, 12 Oct 2018 10:39:53 -0700 Subject: [PATCH 1/8] Initial FS-1065 implementation --- src/absil/illib.fs | 4 - src/fsharp/FSharp.Core/option.fs | 207 +++++-- src/fsharp/FSharp.Core/option.fsi | 578 ++++++++++++------ src/fsharp/FSharp.Core/prim-types.fs | 17 + src/fsharp/FSharp.Core/prim-types.fsi | 14 + .../Microsoft.FSharp.Core/OptionModule.fs | 240 +++++++- 6 files changed, 777 insertions(+), 283 deletions(-) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index ab92a747b5e..3d95265f651 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -432,12 +432,8 @@ 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))) -[] module ValueOption = 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 - let inline isNone x = match x with ValueSome _ -> false | ValueNone -> true type String with member inline x.StartsWithOrdinal(value) = diff --git a/src/fsharp/FSharp.Core/option.fs b/src/fsharp/FSharp.Core/option.fs index f963c01fc79..3744d0a7ade 100644 --- a/src/fsharp/FSharp.Core/option.fs +++ b/src/fsharp/FSharp.Core/option.fs @@ -2,91 +2,176 @@ namespace Microsoft.FSharp.Core - open Microsoft.FSharp.Core.Operators +open Microsoft.FSharp.Core.Operators - [] - module Option = +module Option = - [] - let get option = match option with None -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | Some x -> x + [] + let get option = match option with None -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | Some x -> x - [] - let inline isSome option = match option with None -> false | Some _ -> true + [] + let inline isSome option = match option with None -> false | Some _ -> true - [] - let inline isNone option = match option with None -> true | Some _ -> false + [] + let inline isNone option = match option with None -> true | Some _ -> false - [] - let defaultValue value option = match option with None -> value | Some v -> v + [] + let defaultValue value option = match option with None -> value | Some v -> v - [] - let defaultWith defThunk option = match option with None -> defThunk () | Some v -> v + [] + let defaultWith defThunk option = match option with None -> defThunk () | Some v -> v - [] - let orElse ifNone option = match option with None -> ifNone | Some _ -> option + [] + let orElse ifNone option = match option with None -> ifNone | Some _ -> option - [] - let orElseWith ifNoneThunk option = match option with None -> ifNoneThunk () | Some _ -> option + [] + let orElseWith ifNoneThunk option = match option with None -> ifNoneThunk () | Some _ -> option - [] - let count option = match option with None -> 0 | Some _ -> 1 + [] + let count option = match option with None -> 0 | Some _ -> 1 - [] - let fold<'T,'State> folder (state:'State) (option: option<'T>) = match option with None -> state | Some x -> folder state x + [] + let fold<'T,'State> folder (state:'State) (option: option<'T>) = match option with None -> state | Some x -> folder state x - [] - let foldBack<'T,'State> folder (option: option<'T>) (state:'State) = match option with None -> state | Some x -> folder x state + [] + let foldBack<'T,'State> folder (option: option<'T>) (state:'State) = match option with None -> state | Some x -> folder x state - [] - let exists predicate option = match option with None -> false | Some x -> predicate x + [] + let exists predicate option = match option with None -> false | Some x -> predicate x - [] - let forall predicate option = match option with None -> true | Some x -> predicate x + [] + let forall predicate option = match option with None -> true | Some x -> predicate x - [] - let inline contains value option = match option with None -> false | Some v -> v = value + [] + let inline contains value option = match option with None -> false | Some v -> v = value - [] - let iter action option = match option with None -> () | Some x -> action x + [] + let iter action option = match option with None -> () | Some x -> action x - [] - let map mapping option = match option with None -> None | Some x -> Some (mapping x) + [] + let map mapping option = match option with None -> None | Some x -> Some (mapping x) - [] - let map2 mapping option1 option2 = - match option1, option2 with - | Some x, Some y -> Some (mapping x y) - | _ -> None + [] + let map2 mapping option1 option2 = + match option1, option2 with + | Some x, Some y -> Some (mapping x y) + | _ -> None - [] - let map3 mapping option1 option2 option3 = - match option1, option2, option3 with - | Some x, Some y, Some z -> Some (mapping x y z) - | _ -> None + [] + let map3 mapping option1 option2 option3 = + match option1, option2, option3 with + | Some x, Some y, Some z -> Some (mapping x y z) + | _ -> None - [] - let bind binder option = match option with None -> None | Some x -> binder x + [] + let bind binder option = match option with None -> None | Some x -> binder x - [] - let flatten option = match option with None -> None | Some x -> x + [] + let flatten option = match option with None -> None | Some x -> x - [] - let filter predicate option = match option with None -> None | Some x -> if predicate x then Some x else None + [] + let filter predicate option = match option with None -> None | Some x -> if predicate x then Some x else None - [] - let toArray option = match option with None -> [| |] | Some x -> [| x |] + [] + let toArray option = match option with None -> [| |] | Some x -> [| x |] - [] - let toList option = match option with None -> [ ] | Some x -> [ x ] + [] + let toList option = match option with None -> [ ] | Some x -> [ x ] - [] - let toNullable option = match option with None -> System.Nullable() | Some v -> System.Nullable(v) + [] + let toNullable option = match option with None -> System.Nullable() | Some v -> System.Nullable(v) - [] - let ofNullable (value:System.Nullable<'T>) = if value.HasValue then Some value.Value else None + [] + let ofNullable (value:System.Nullable<'T>) = if value.HasValue then Some value.Value else None - [] - let ofObj value = match value with null -> None | _ -> Some value + [] + let ofObj value = match value with null -> None | _ -> Some value - [] - let toObj value = match value with None -> null | Some x -> x + [] + let toObj value = match value with None -> null | Some x -> x + +module ValueOption = + + [] + let get voption = match voption with ValueNone -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | ValueSome x -> x + + [] + let inline isSome voption = match voption with ValueNone -> false | ValueSome _ -> true + + [] + let inline isNone voption = match voption with ValueNone -> true | ValueSome _ -> false + + [] + let defaultValue value voption = match voption with ValueNone -> value | ValueSome v -> v + + [] + let defaultWith defThunk voption = match voption with ValueNone -> defThunk () | ValueSome v -> v + + [] + let orElse ifNone voption = match voption with ValueNone -> ifNone | ValueSome _ -> voption + + [] + let orElseWith ifNoneThunk voption = match voption with ValueNone -> ifNoneThunk () | ValueSome _ -> voption + + [] + let count voption = match voption with ValueNone -> 0 | ValueSome _ -> 1 + + [] + let fold<'T,'State> folder (state:'State) (voption: voption<'T>) = match voption with ValueNone -> state | ValueSome x -> folder state x + + [] + let foldBack<'T,'State> folder (voption: voption<'T>) (state:'State) = match voption with ValueNone -> state | ValueSome x -> folder x state + + [] + let exists predicate voption = match voption with ValueNone -> false | ValueSome x -> predicate x + + [] + let forall predicate voption = match voption with ValueNone -> true | ValueSome x -> predicate x + + [] + let inline contains value voption = match voption with ValueNone -> false | ValueSome v -> v = value + + [] + let iter action voption = match voption with ValueNone -> () | ValueSome x -> action x + + [] + let map mapping voption = match voption with ValueNone -> ValueNone | ValueSome x -> ValueSome (mapping x) + + [] + let map2 mapping voption1 voption2 = + match voption1, voption2 with + | ValueSome x, ValueSome y -> ValueSome (mapping x y) + | _ -> ValueNone + + [] + let map3 mapping voption1 voption2 voption3 = + match voption1, voption2, voption3 with + | ValueSome x, ValueSome y, ValueSome z -> ValueSome (mapping x y z) + | _ -> ValueNone + + [] + let bind binder voption = match voption with ValueNone -> ValueNone | ValueSome x -> binder x + + [] + let flatten voption = match voption with ValueNone -> ValueNone | ValueSome x -> x + + [] + let filter predicate voption = match voption with ValueNone -> ValueNone | ValueSome x -> if predicate x then ValueSome x else ValueNone + + [] + let toArray voption = match voption with ValueNone -> [| |] | ValueSome x -> [| x |] + + [] + let toList voption = match voption with ValueNone -> [ ] | ValueSome x -> [ x ] + + [] + let toNullable voption = match voption with ValueNone -> System.Nullable() | ValueSome v -> System.Nullable(v) + + [] + let ofNullable (value:System.Nullable<'T>) = if value.HasValue then ValueSome value.Value else ValueNone + + [] + let ofObj value = match value with null -> ValueNone | _ -> ValueSome value + + [] + let toObj value = match value with ValueNone -> null | ValueSome x -> x diff --git a/src/fsharp/FSharp.Core/option.fsi b/src/fsharp/FSharp.Core/option.fsi index a8f7af2ffce..beb8dafe04d 100644 --- a/src/fsharp/FSharp.Core/option.fsi +++ b/src/fsharp/FSharp.Core/option.fsi @@ -2,199 +2,385 @@ namespace Microsoft.FSharp.Core - open System - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - open Microsoft.FSharp.Core.Operators - open Microsoft.FSharp.Collections - - [] - /// Basic operations on options. - module Option = - /// Returns true if the option is not None. - /// The input option. - /// True if the option is not None. - [] - val inline isSome: option:'T option -> bool - - /// Returns true if the option is None. - /// The input option. - /// True if the option is None. - [] - val inline isNone: option:'T option -> bool - - /// Gets the value of the option if the option is Some, otherwise returns the specified default value. - /// The specified default value. - /// The input option. - /// The option if the option is Some, else the default value. - /// Identical to the built-in operator, except with the arguments swapped. - [] - val defaultValue: value:'T -> option:'T option -> 'T - - /// Gets the value of the option if the option is Some, otherwise evaluates and returns the result. - /// A thunk that provides a default value when evaluated. - /// The input option. - /// The option if the option is Some, else the result of evaluating . - /// is not evaluated unless is None. - [] - val defaultWith: defThunk:(unit -> 'T) -> option:'T option -> 'T - - /// Returns if it is Some, otherwise returns . - /// The value to use if is None. - /// The input option. - /// The option if the option is Some, else the alternate option. - [] - val orElse: ifNone:'T option -> option:'T option -> 'T option - - /// Returns if it is Some, otherwise evaluates and returns the result. - /// A thunk that provides an alternate option when evaluated. - /// The input option. - /// The option if the option is Some, else the result of evaluating . - /// is not evaluated unless is None. - [] - val orElseWith: ifNoneThunk:(unit -> 'T option) -> option:'T option -> 'T option - - /// Gets the value associated with the option. - /// The input option. - /// The value within the option. - /// Thrown when the option is None. - [] - val get: option:'T option -> 'T - - /// count inp evaluates to match inp with None -> 0 | Some _ -> 1. - /// The input option. - /// A zero if the option is None, a one otherwise. - [] - val count: option:'T option -> int - - /// fold f s inp evaluates to match inp with None -> s | Some x -> f s x. - /// A function to update the state data when given a value from an option. - /// The initial state. - /// The input option. - /// The original state if the option is None, otherwise it returns the updated state with the folder - /// and the option value. - [] - val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> option:'T option -> 'State - - /// fold f inp s evaluates to match inp with None -> s | Some x -> f x s. - /// A function to update the state data when given a value from an option. - /// The input option. - /// The initial state. - /// The original state if the option is None, otherwise it returns the updated state with the folder - /// and the option value. - [] - val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> option:'T option -> state:'State -> 'State - - /// exists p inp evaluates to match inp with None -> false | Some x -> p x. - /// A function that evaluates to a boolean when given a value from the option type. - /// The input option. - /// False if the option is None, otherwise it returns the result of applying the predicate - /// to the option value. - [] - val exists: predicate:('T -> bool) -> option:'T option -> bool - - /// forall p inp evaluates to match inp with None -> true | Some x -> p x. - /// A function that evaluates to a boolean when given a value from the option type. - /// The input option. - /// True if the option is None, otherwise it returns the result of applying the predicate - /// to the option value. - [] - val forall: predicate:('T -> bool) -> option:'T option -> bool - - /// Evaluates to true if is Some and its value is equal to . - /// The value to test for equality. - /// The input option. - /// True if the option is Some and contains a value equal to , otherwise false. - [] - val inline contains: value:'T -> option:'T option -> bool when 'T : equality - - /// iter f inp executes match inp with None -> () | Some x -> f x. - /// A function to apply to the option value. - /// The input option. - /// Unit if the option is None, otherwise it returns the result of applying the predicate - /// to the option value. - [] - val iter: action:('T -> unit) -> option:'T option -> unit - - /// map f inp evaluates to match inp with None -> None | Some x -> Some (f x). - /// A function to apply to the option value. - /// The input option. - /// An option of the input value after applying the mapping function, or None if the input is None. - [] - val map: mapping:('T -> 'U) -> option:'T option -> 'U option - - /// map f option1 option2 evaluates to match option1, option2 with Some x, Some y -> Some (f x y) | _ -> None. - /// A function to apply to the option values. - /// The first option. - /// The second option. - /// An option of the input values after applying the mapping function, or None if either input is None. - [] - val map2: mapping:('T1 -> 'T2 -> 'U) -> 'T1 option -> 'T2 option -> 'U option - - /// map f option1 option2 option3 evaluates to match option1, option2, option3 with Some x, Some y, Some z -> Some (f x y z) | _ -> None. - /// A function to apply to the option values. - /// The first option. - /// The second option. - /// The third option. - /// An option of the input values after applying the mapping function, or None if any input is None. - [] - val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> 'T1 option -> 'T2 option -> 'T3 option -> 'U option - - /// bind f inp evaluates to match inp with None -> None | Some x -> f x - /// A function that takes the value of type T from an option and transforms it into - /// an option containing a value of type U. - /// The input option. - /// An option of the output type of the binder. - [] - val bind: binder:('T -> 'U option) -> option:'T option -> 'U option - - /// flatten inp evaluates to match inp with None -> None | Some x -> x - /// The input option. - /// An option of the output type of the binder. - /// flatten is equivalent to bind id. - [] - val flatten: option:'T option option -> 'T option - - /// filter f inp evaluates to match inp with None -> None | Some x -> if f x then Some x else None. - /// A function that evaluates whether the value contained in the option should remain, or be filtered out. - /// The input option. - /// The input if the predicate evaluates to true; otherwise, None. - [] - val filter: predicate:('T -> bool) -> option:'T option -> 'T option - - /// Convert the option to an array of length 0 or 1. - /// The input option. - /// The result array. - [] - val toArray: option:'T option -> 'T[] - - /// Convert the option to a list of length 0 or 1. - /// The input option. - /// The result list. - [] - val toList: option:'T option -> 'T list - - - /// Convert the option to a Nullable value. - /// The input option. - /// The result value. - [] - val toNullable: option:'T option -> Nullable<'T> - - /// Convert a Nullable value to an option. - /// The input nullable value. - /// The result option. - [] - val ofNullable: value:Nullable<'T> -> 'T option - - /// Convert a potentially null value to an option. - /// The input value. - /// The result option. - [] - val ofObj: value: 'T -> 'T option when 'T : null - - /// Convert an option to a potentially null value. - /// The input value. - /// The result value, which is null if the input was None. - [] - val toObj: value: 'T option -> 'T when 'T : null +open System +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +/// Basic operations on options. +module Option = + /// Returns true if the option is not None. + /// The input option. + /// True if the option is not None. + [] + val inline isSome: option:'T option -> bool + + /// Returns true if the option is None. + /// The input option. + /// True if the option is None. + [] + val inline isNone: option:'T option -> bool + + /// Gets the value of the option if the option is Some, otherwise returns the specified default value. + /// The specified default value. + /// The input option. + /// The option if the option is Some, else the default value. + /// Identical to the built-in operator, except with the arguments swapped. + [] + val defaultValue: value:'T -> option:'T option -> 'T + + /// Gets the value of the option if the option is Some, otherwise evaluates and returns the result. + /// A thunk that provides a default value when evaluated. + /// The input option. + /// The option if the option is Some, else the result of evaluating . + /// is not evaluated unless is None. + [] + val defaultWith: defThunk:(unit -> 'T) -> option:'T option -> 'T + + /// Returns if it is Some, otherwise returns . + /// The value to use if is None. + /// The input option. + /// The option if the option is Some, else the alternate option. + [] + val orElse: ifNone:'T option -> option:'T option -> 'T option + + /// Returns if it is Some, otherwise evaluates and returns the result. + /// A thunk that provides an alternate option when evaluated. + /// The input option. + /// The option if the option is Some, else the result of evaluating . + /// is not evaluated unless is None. + [] + val orElseWith: ifNoneThunk:(unit -> 'T option) -> option:'T option -> 'T option + + /// Gets the value associated with the option. + /// The input option. + /// The value within the option. + /// Thrown when the option is None. + [] + val get: option:'T option -> 'T + + /// count inp evaluates to match inp with None -> 0 | Some _ -> 1. + /// The input option. + /// A zero if the option is None, a one otherwise. + [] + val count: option:'T option -> int + + /// fold f s inp evaluates to match inp with None -> s | Some x -> f s x. + /// A function to update the state data when given a value from an option. + /// The initial state. + /// The input option. + /// The original state if the option is None, otherwise it returns the updated state with the folder + /// and the option value. + [] + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> option:'T option -> 'State + + /// fold f inp s evaluates to match inp with None -> s | Some x -> f x s. + /// A function to update the state data when given a value from an option. + /// The input option. + /// The initial state. + /// The original state if the option is None, otherwise it returns the updated state with the folder + /// and the option value. + [] + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> option:'T option -> state:'State -> 'State + + /// exists p inp evaluates to match inp with None -> false | Some x -> p x. + /// A function that evaluates to a boolean when given a value from the option type. + /// The input option. + /// False if the option is None, otherwise it returns the result of applying the predicate + /// to the option value. + [] + val exists: predicate:('T -> bool) -> option:'T option -> bool + + /// forall p inp evaluates to match inp with None -> true | Some x -> p x. + /// A function that evaluates to a boolean when given a value from the option type. + /// The input option. + /// True if the option is None, otherwise it returns the result of applying the predicate + /// to the option value. + [] + val forall: predicate:('T -> bool) -> option:'T option -> bool + + /// Evaluates to true if is Some and its value is equal to . + /// The value to test for equality. + /// The input option. + /// True if the option is Some and contains a value equal to , otherwise false. + [] + val inline contains: value:'T -> option:'T option -> bool when 'T : equality + + /// iter f inp executes match inp with None -> () | Some x -> f x. + /// A function to apply to the option value. + /// The input option. + /// Unit if the option is None, otherwise it returns the result of applying the predicate + /// to the option value. + [] + val iter: action:('T -> unit) -> option:'T option -> unit + + /// map f inp evaluates to match inp with None -> None | Some x -> Some (f x). + /// A function to apply to the option value. + /// The input option. + /// An option of the input value after applying the mapping function, or None if the input is None. + [] + val map: mapping:('T -> 'U) -> option:'T option -> 'U option + + /// map f option1 option2 evaluates to match option1, option2 with Some x, Some y -> Some (f x y) | _ -> None. + /// A function to apply to the option values. + /// The first option. + /// The second option. + /// An option of the input values after applying the mapping function, or None if either input is None. + [] + val map2: mapping:('T1 -> 'T2 -> 'U) -> 'T1 option -> 'T2 option -> 'U option + + /// map f option1 option2 option3 evaluates to match option1, option2, option3 with Some x, Some y, Some z -> Some (f x y z) | _ -> None. + /// A function to apply to the option values. + /// The first option. + /// The second option. + /// The third option. + /// An option of the input values after applying the mapping function, or None if any input is None. + [] + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> 'T1 option -> 'T2 option -> 'T3 option -> 'U option + + /// bind f inp evaluates to match inp with None -> None | Some x -> f x + /// A function that takes the value of type T from an option and transforms it into + /// an option containing a value of type U. + /// The input option. + /// An option of the output type of the binder. + [] + val bind: binder:('T -> 'U option) -> option:'T option -> 'U option + + /// flatten inp evaluates to match inp with None -> None | Some x -> x + /// The input option. + /// An option of the output type of the binder. + /// flatten is equivalent to bind id. + [] + val flatten: option:'T option option -> 'T option + + /// filter f inp evaluates to match inp with None -> None | Some x -> if f x then Some x else None. + /// A function that evaluates whether the value contained in the option should remain, or be filtered out. + /// The input option. + /// The input if the predicate evaluates to true; otherwise, None. + [] + val filter: predicate:('T -> bool) -> option:'T option -> 'T option + + /// Convert the option to an array of length 0 or 1. + /// The input option. + /// The result array. + [] + val toArray: option:'T option -> 'T[] + + /// Convert the option to a list of length 0 or 1. + /// The input option. + /// The result list. + [] + val toList: option:'T option -> 'T list + + + /// Convert the option to a Nullable value. + /// The input option. + /// The result value. + [] + val toNullable: option:'T option -> Nullable<'T> + + /// Convert a Nullable value to an option. + /// The input nullable value. + /// The result option. + [] + val ofNullable: value:Nullable<'T> -> 'T option + + /// Convert a potentially null value to an option. + /// The input value. + /// The result option. + [] + val ofObj: value: 'T -> 'T option when 'T : null + + /// Convert an option to a potentially null value. + /// The input value. + /// The result value, which is null if the input was None. + [] + val toObj: value: 'T option -> 'T when 'T : null + +/// Basic operations on value options. +module ValueOption = + /// Returns true if the value option is not ValueNone. + /// The input value option. + /// True if the value option is not ValueNone. + [] + val inline isSome: voption:'T voption -> bool + + /// Returns true if the value option is ValueNone. + /// The input value option. + /// True if the voption is ValueNone. + [] + val inline isNone: voption:'T voption -> bool + + /// Gets the value of the value option if the option is ValueSome, otherwise returns the specified default value. + /// The specified default value. + /// The input voption. + /// The voption if the voption is ValueSome, else the default value. + /// Identical to the built-in operator, except with the arguments swapped. + [] + val defaultValue: value:'T -> voption:'T voption -> 'T + + /// Gets the value of the voption if the voption is ValueSome, otherwise evaluates and returns the result. + /// A thunk that provides a default value when evaluated. + /// The input voption. + /// The voption if the voption is ValueSome, else the result of evaluating . + /// is not evaluated unless is ValueNone. + [] + val defaultWith: defThunk:(unit -> 'T) -> voption:'T voption -> 'T + + /// Returns if it is Some, otherwise returns . + /// The value to use if is None. + /// The input option. + /// The option if the option is Some, else the alternate option. + [] + val orElse: ifNone:'T voption -> voption:'T voption -> 'T voption + + /// Returns if it is Some, otherwise evaluates and returns the result. + /// A thunk that provides an alternate value option when evaluated. + /// The input value option. + /// The voption if the voption is ValueSome, else the result of evaluating . + /// is not evaluated unless is ValueNone. + [] + val orElseWith: ifNoneThunk:(unit -> 'T voption) -> voption:'T voption -> 'T voption + + /// Gets the value associated with the option. + /// The input value option. + /// The value within the option. + /// Thrown when the option is ValueNone. + [] + val get: voption:'T voption -> 'T + + /// count inp evaluates to match inp with ValueNone -> 0 | ValueSome _ -> 1. + /// The input value option. + /// A zero if the option is ValueNone, a one otherwise. + [] + val count: voption:'T voption -> int + + /// fold f s inp evaluates to match inp with ValueNone -> s | ValueSome x -> f s x. + /// A function to update the state data when given a value from a value option. + /// The initial state. + /// The input value option. + /// The original state if the option is ValueNone, otherwise it returns the updated state with the folder + /// and the voption value. + [] + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> voption:'T voption -> 'State + + /// fold f inp s evaluates to match inp with ValueNone -> s | ValueSome x -> f x s. + /// A function to update the state data when given a value from a value option. + /// The input value option. + /// The initial state. + /// The original state if the option is ValueNone, otherwise it returns the updated state with the folder + /// and the voption value. + [] + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> voption:'T voption -> state:'State -> 'State + + /// exists p inp evaluates to match inp with ValueNone -> false | ValueSome x -> p x. + /// A function that evaluates to a boolean when given a value from the option type. + /// The input value option. + /// False if the option is ValueNone, otherwise it returns the result of applying the predicate + /// to the option value. + [] + val exists: predicate:('T -> bool) -> voption:'T voption -> bool + + /// forall p inp evaluates to match inp with ValueNone -> true | ValueSome x -> p x. + /// A function that evaluates to a boolean when given a value from the value option type. + /// The input value option. + /// True if the option is None, otherwise it returns the result of applying the predicate + /// to the option value. + [] + val forall: predicate:('T -> bool) -> voption:'T voption -> bool + + /// Evaluates to true if is ValueSome and its value is equal to . + /// The value to test for equality. + /// The input value option. + /// True if the option is ValueSome and contains a value equal to , otherwise false. + [] + val inline contains: value:'T -> voption:'T voption -> bool when 'T : equality + + /// iter f inp executes match inp with ValueNone -> () | ValueSome x -> f x. + /// A function to apply to the voption value. + /// The input value option. + /// Unit if the option is ValueNone, otherwise it returns the result of applying the predicate + /// to the voption value. + [] + val iter: action:('T -> unit) -> voption:'T voption -> unit + + /// map f inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> ValueSome (f x). + /// A function to apply to the voption value. + /// The input value option. + /// A value option of the input value after applying the mapping function, or ValueNone if the input is ValueNone. + [] + val map: mapping:('T -> 'U) -> voption:'T voption -> 'U voption + + /// map f voption1 voption2 evaluates to match voption1, voption2 with ValueSome x, ValueSome y -> ValueSome (f x y) | _ -> ValueNone. + /// A function to apply to the voption values. + /// The first value option. + /// The second value option. + /// A value option of the input values after applying the mapping function, or ValueNone if either input is ValueNone. + [] + val map2: mapping:('T1 -> 'T2 -> 'U) -> voption1: 'T1 voption -> voption2: 'T2 voption -> 'U voption + + /// map f voption1 voption2 voption3 evaluates to match voption1, voption2, voption3 with ValueSome x, ValueSome y, ValueSome z -> ValueSome (f x y z) | _ -> ValueNone. + /// A function to apply to the value option values. + /// The first value option. + /// The second value option. + /// The third value option. + /// A value option of the input values after applying the mapping function, or ValueNone if any input is ValueNone. + [] + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> 'T1 voption -> 'T2 voption -> 'T3 voption -> 'U voption + + /// bind f inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> f x + /// A function that takes the value of type T from a value option and transforms it into + /// a value option containing a value of type U. + /// The input value option. + /// An option of the output type of the binder. + [] + val bind: binder:('T -> 'U voption) -> voption:'T voption -> 'U voption + + /// flatten inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> x + /// The input value option. + /// A value option of the output type of the binder. + /// flatten is equivalent to bind id. + [] + val flatten: voption:'T voption voption -> 'T voption + + /// filter f inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> if f x then ValueSome x else ValueNone. + /// A function that evaluates whether the value contained in the value option should remain, or be filtered out. + /// The input value option. + /// The input if the predicate evaluates to true; otherwise, ValueNone. + [] + val filter: predicate:('T -> bool) -> voption:'T voption -> 'T voption + + /// Convert the value option to an array of length 0 or 1. + /// The input value option. + /// The result array. + [] + val toArray: voption:'T voption -> 'T[] + + /// Convert the value option to a list of length 0 or 1. + /// The input value option. + /// The result list. + [] + val toList: voption:'T voption -> 'T list + + /// Convert the value option to a Nullable value. + /// The input value option. + /// The result value. + [] + val toNullable: voption:'T voption -> Nullable<'T> + + /// Convert a Nullable value to a value option. + /// The input nullable value. + /// The result value option. + [] + val ofNullable: value:Nullable<'T> -> 'T voption + + /// Convert a potentially null value to a value option. + /// The input value. + /// The result value option. + [] + val ofObj: value: 'T -> 'T voption when 'T : null + + /// Convert an option to a potentially null value. + /// The input value. + /// The result value, which is null if the input was ValueNone. + [] + val toObj: value: 'T voption -> 'T when 'T : null diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 753a75204dc..7929ef77581 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3054,12 +3054,29 @@ namespace Microsoft.FSharp.Core [] [] [] + [] type ValueOption<'T> = | ValueNone : 'T voption | ValueSome : 'T -> 'T voption member x.Value = match x with ValueSome x -> x | ValueNone -> raise (new System.InvalidOperationException("ValueOption.Value")) + [] + static member None : 'T voption = ValueNone + + static member Some (value) : 'T voption = ValueSome(value) + + [] + member x.IsNone = match x with ValueNone -> true | _ -> false + + [] + member x.IsSome = match x with ValueSome _ -> true | _ -> false + + static member op_Implicit (value) : 'T option = Some(value) + + override x.ToString() = + // x is non-null, hence ValueSome + "ValueSome("^anyToStringShowingNull x.Value^")" and 'T voption = ValueOption<'T> diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 61786826a20..a62b9d18783 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -1866,6 +1866,20 @@ namespace Microsoft.FSharp.Core /// Get the value of a 'ValueSome' option. An InvalidOperationException is raised if the option is 'ValueNone'. member Value : 'T + /// Create a value option value that is a 'ValueNone' value. + static member None : 'T voption + + /// Create a value option value that is a 'Some' value. + /// The input value + /// A value option representing the value. + static member Some : value:'T -> 'T voption + + /// Return 'true' if the value option is a 'ValueSome' value. + member IsSome : bool + + /// Return 'true' if the value option is a 'ValueNone' value. + member IsNone : bool + /// The type of optional values, represented as structs. /// /// Use the constructors ValueSome and ValueNone to create values of this type. diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs index 5726775deff..3fb4395cd69 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs @@ -224,28 +224,224 @@ type ValueOptionTests() = [] member this.ValueOptionBasics () = - Assert.AreEqual( (ValueNone: int voption), (ValueNone: int voption)) - Assert.True( (ValueNone: int voption) <= (ValueNone: int voption)) - Assert.True( (ValueNone: int voption) >= (ValueNone: int voption)) - Assert.True( (ValueNone: int voption) < (ValueSome 1: int voption)) - Assert.True( (ValueSome 0: int voption) < (ValueSome 1: int voption)) - Assert.True( (ValueSome 1: int voption) > (ValueSome 0: int voption)) - Assert.False( (ValueSome 1: int voption) < (ValueNone : int voption)) - Assert.True( (ValueSome 1: int voption) <= (ValueSome 1: int voption)) - Assert.AreEqual( compare (ValueSome 1) (ValueSome 1), 0) - Assert.True( compare (ValueSome 0) (ValueSome 1) < 0) - Assert.True( compare (ValueNone: int voption) (ValueSome 1) < 0) - Assert.True( compare (ValueSome 1) (ValueNone : int voption) > 0) - Assert.AreEqual( ValueSome 1, ValueSome 1) - Assert.AreNotEqual( ValueSome 2, ValueSome 1) - Assert.AreEqual( ValueSome 2, ValueSome 2) - Assert.AreEqual( ValueSome (ValueSome 2), ValueSome (ValueSome 2)) - Assert.AreNotEqual( ValueSome (ValueSome 2), ValueSome (ValueSome 1)) - Assert.AreNotEqual( ValueSome (ValueSome 0), ValueSome ValueNone) - Assert.AreEqual( ValueSome (ValueNone: int voption), ValueSome (ValueNone: int voption)) - Assert.AreEqual( (ValueSome (ValueNone: int voption)).Value, (ValueNone: int voption)) - Assert.AreEqual( (ValueSome 1).Value, 1) - Assert.AreEqual( (ValueSome (1,2)).Value, (1,2)) + Assert.AreEqual((ValueNone: int voption), (ValueNone: int voption)) + Assert.True((ValueNone: int voption) <= (ValueNone: int voption)) + Assert.True((ValueNone: int voption) >= (ValueNone: int voption)) + Assert.True((ValueNone: int voption) < (ValueSome 1: int voption)) + Assert.True((ValueSome 0: int voption) < (ValueSome 1: int voption)) + Assert.True((ValueSome 1: int voption) > (ValueSome 0: int voption)) + Assert.False((ValueSome 1: int voption) < (ValueNone : int voption)) + Assert.True((ValueSome 1: int voption) <= (ValueSome 1: int voption)) + Assert.AreEqual(compare (ValueSome 1) (ValueSome 1), 0) + Assert.True(compare (ValueSome 0) (ValueSome 1) < 0) + Assert.True(compare (ValueNone: int voption) (ValueSome 1) < 0) + Assert.True(compare (ValueSome 1) (ValueNone : int voption) > 0) + Assert.AreEqual(ValueSome 1, ValueSome 1) + Assert.AreNotEqual(ValueSome 2, ValueSome 1) + Assert.AreEqual(ValueSome 2, ValueSome 2) + Assert.AreEqual(ValueSome (ValueSome 2), ValueSome (ValueSome 2)) + Assert.AreNotEqual(ValueSome (ValueSome 2), ValueSome (ValueSome 1)) + Assert.AreNotEqual(ValueSome (ValueSome 0), ValueSome ValueNone) + Assert.AreEqual(ValueSome (ValueNone: int voption), ValueSome (ValueNone: int voption)) + Assert.AreEqual((ValueSome (ValueNone: int voption)).Value, (ValueNone: int voption)) + Assert.AreEqual((ValueSome 1).Value, 1) + Assert.AreEqual((ValueSome (1,2)).Value, (1,2)) Assert.AreEqual(defaultValueArg ValueNone 1, 1) Assert.AreEqual(defaultValueArg (ValueSome 3) 1, 3) + + [] + member this.Flatten () = + Assert.AreEqual(ValueOption.flatten ValueNone, ValueNone) + Assert.AreEqual(ValueOption.flatten (ValueSome ValueNone), ValueNone) + Assert.AreEqual(ValueOption.flatten (ValueSome <| ValueSome 1), ValueSome 1) + Assert.AreEqual(ValueOption.flatten (ValueSome <| ValueSome ""), ValueSome "") + + [] + member this.FilterValueSomeIntegerWhenPredicateReturnsTrue () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter (fun _ -> true) + + actual = ValueSome x + |> Assert.True + [0;1;-1;42] |> List.iter test + + [] + member this.FilterValueSomeStringWhenPredicateReturnsTrue () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter (fun _ -> true) + + actual = ValueSome x + |> Assert.True + [""; " "; "Foo"; "Bar"] |> List.iter test + + [] + member this.FilterValueSomeIntegerWhenPredicateReturnsFalse () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter (fun _ -> false) + + actual = ValueNone + |> Assert.True + [0; 1; -1; 1337] |> List.iter test + + [] + member this.FilterValueSomeStringWhenPredicateReturnsFalse () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter (fun _ -> false) + + actual= ValueNone + |> Assert.True + [""; " "; "Ploeh"; "Fnaah"] |> List.iter test + [] + member this.FilterValueNoneReturnsCorrectResult () = + let test x = + let actual = ValueNone |> ValueOption.filter (fun _ -> x) + + actual = ValueNone + |> Assert.True + [false; true] |> List.iter test + + [] + member this.FilterValueSomeIntegerWhenPredicateEqualsInput () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter ((=) x) + + actual = ValueSome x + |> Assert.True + [0; 1; -1; -2001] |> List.iter test + + [] + member this.FilterValueSomeStringWhenPredicateEqualsInput () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter ((=) x) + + actual = ValueSome x + |> Assert.True + [""; " "; "Xyzz"; "Sgryt"] |> List.iter test + + [] + member this.FilterValueSomeIntegerWhenPredicateDoesNotEqualsInput () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter ((<>) x) + + actual = ValueNone + |> Assert.True + [0; 1; -1; 927] |> List.iter test + + [] + member this.FilterValueSomeStringWhenPredicateDoesNotEqualsInput () = + let test x = + let actual = x |> ValueSome |> ValueOption.filter ((<>) x) + + actual = ValueNone + |> Assert.True + [""; " "; "Baz Quux"; "Corge grault"] |> List.iter test + + [] + member this.Contains() = + Assert.IsFalse(ValueOption.contains 1 ValueNone) + Assert.IsTrue(ValueOption.contains 1 (ValueSome 1)) + + Assert.IsFalse(ValueOption.contains "" ValueNone) + Assert.IsTrue(ValueOption.contains "" (ValueSome "")) + + Assert.IsFalse(ValueOption.contains ValueNone ValueNone) + Assert.IsTrue(ValueOption.contains ValueNone (ValueSome ValueNone)) + [] + member this.OfToNullable() = + Assert.IsTrue(ValueOption.ofNullable (System.Nullable()) = ValueNone) + Assert.IsTrue(ValueOption.ofNullable (System.Nullable(3)) = ValueSome 3) + + Assert.IsTrue(ValueOption.toNullable (ValueNone : int voption) = System.Nullable()) + Assert.IsTrue(ValueOption.toNullable (ValueNone : System.DateTime voption) = System.Nullable()) + Assert.IsTrue(ValueOption.toNullable (ValueSome 3) = System.Nullable(3)) + + [] + member this.OfToObj() = + Assert.IsTrue(ValueOption.toObj (ValueSome "3") = "3") + Assert.IsTrue(ValueOption.toObj (ValueSome "") = "") + Assert.IsTrue(ValueOption.toObj (ValueSome null) = null) + Assert.IsTrue(ValueOption.toObj ValueNone = null) + + Assert.IsTrue(ValueOption.ofObj "3" = ValueSome "3") + Assert.IsTrue(ValueOption.ofObj "" = ValueSome "") + Assert.IsTrue(ValueOption.ofObj [| "" |] = ValueSome [| "" |]) + Assert.IsTrue(ValueOption.ofObj (null : string array) = ValueNone) + Assert.IsTrue(ValueOption.ofObj null = ValueNone) + Assert.IsTrue(ValueOption.ofObj null = ValueNone) + Assert.IsTrue(ValueOption.ofObj null = ValueNone) + + [] + member this.DefaultValue() = + Assert.AreEqual(ValueOption.defaultValue 3 ValueNone, 3) + Assert.AreEqual(ValueOption.defaultValue 3 (ValueSome 42), 42) + Assert.AreEqual(ValueOption.defaultValue "" ValueNone, "") + Assert.AreEqual(ValueOption.defaultValue "" (ValueSome "x"), "x") + + [] + member this.DefaultWith() = + Assert.AreEqual(ValueOption.defaultWith (fun () -> 3) ValueNone, 3) + Assert.AreEqual(ValueOption.defaultWith (fun () -> "") ValueNone, "") + + Assert.AreEqual(ValueOption.defaultWith assertWasNotCalledThunk (ValueSome 42), 42) + Assert.AreEqual(ValueOption.defaultWith assertWasNotCalledThunk (ValueSome ""), "") + + [] + member this.OrElse() = + Assert.AreEqual(ValueOption.orElse ValueNone ValueNone, ValueNone) + Assert.AreEqual(ValueOption.orElse (ValueSome 3) ValueNone, ValueSome 3) + Assert.AreEqual(ValueOption.orElse ValueNone (ValueSome 42), ValueSome 42) + Assert.AreEqual(ValueOption.orElse (ValueSome 3) (ValueSome 42), ValueSome 42) + + Assert.AreEqual(ValueOption.orElse (ValueSome "") ValueNone, ValueSome "") + Assert.AreEqual(ValueOption.orElse ValueNone (ValueSome "x"), ValueSome "x") + Assert.AreEqual(ValueOption.orElse (ValueSome "") (ValueSome "x"), ValueSome "x") + + [] + member this.OrElseWith() = + Assert.AreEqual(ValueOption.orElseWith (fun () -> ValueNone) ValueNone, ValueNone) + Assert.AreEqual(ValueOption.orElseWith (fun () -> ValueSome 3) ValueNone, ValueSome 3) + Assert.AreEqual(ValueOption.orElseWith (fun () -> ValueSome "") ValueNone, ValueSome "") + + Assert.AreEqual(ValueOption.orElseWith assertWasNotCalledThunk (ValueSome 42), ValueSome 42) + Assert.AreEqual(ValueOption.orElseWith assertWasNotCalledThunk (ValueSome ""), ValueSome "") + + [] + member this.Map2() = + Assert.True(ValueOption.map2 (-) ValueNone ValueNone = ValueNone) + Assert.True(ValueOption.map2 (-) (ValueSome 1) ValueNone = ValueNone) + Assert.True(ValueOption.map2 (-) ValueNone (ValueSome 2) = ValueNone) + Assert.True(ValueOption.map2 (-) (ValueSome 1) (ValueSome 2) = ValueSome -1) + + Assert.True(ValueOption.map2 (+) ValueNone ValueNone = ValueNone) + Assert.True(ValueOption.map2 (+) (ValueSome "x") ValueNone = ValueNone) + Assert.True(ValueOption.map2 (+) (ValueSome "x") (ValueSome "y") = ValueSome "xy") + Assert.True(ValueOption.map2 (+) ValueNone (ValueSome "y") = ValueNone) + + [] + member this.Map3() = + let add3 x y z = string x + string y + string z + Assert.True(ValueOption.map3 add3 ValueNone ValueNone ValueNone = ValueNone) + Assert.True(ValueOption.map3 add3 (ValueSome 1) ValueNone ValueNone = ValueNone) + Assert.True(ValueOption.map3 add3 ValueNone (ValueSome 2) ValueNone = ValueNone) + Assert.True(ValueOption.map3 add3 (ValueSome 1) (ValueSome 2) ValueNone = ValueNone) + Assert.True(ValueOption.map3 add3 ValueNone ValueNone (ValueSome 3) = ValueNone) + Assert.True(ValueOption.map3 add3 (ValueSome 1) ValueNone (ValueSome 3) = ValueNone) + Assert.True(ValueOption.map3 add3 ValueNone (ValueSome 2) (ValueSome 3) = ValueNone) + Assert.True(ValueOption.map3 add3 (ValueSome 1) (ValueSome 2) (ValueSome 3) = ValueSome "123") + + let concat3 x y z = x + y + z + Assert.True(ValueOption.map3 concat3 ValueNone ValueNone ValueNone = ValueNone) + Assert.True(ValueOption.map3 concat3 (ValueSome "x") ValueNone ValueNone = ValueNone) + Assert.True(ValueOption.map3 concat3 ValueNone (ValueSome "y") ValueNone = ValueNone) + Assert.True(ValueOption.map3 concat3 (ValueSome "x") (ValueSome "y") ValueNone = ValueNone) + Assert.True(ValueOption.map3 concat3 ValueNone ValueNone (ValueSome "z") = ValueNone) + Assert.True(ValueOption.map3 concat3 (ValueSome "x") ValueNone (ValueSome "z") = ValueNone) + Assert.True(ValueOption.map3 concat3 ValueNone (ValueSome "y") (ValueSome "z") = ValueNone) + Assert.True(ValueOption.map3 concat3 (ValueSome "x") (ValueSome "y") (ValueSome "z") = ValueSome "xyz") + + [] + member this.MapBindEquivalenceProperties () = + let fn x = x + 3 + Assert.AreEqual(ValueOption.map fn ValueNone, ValueOption.bind (fn >> ValueSome) ValueNone) + Assert.AreEqual(ValueOption.map fn (ValueSome 5), ValueOption.bind (fn >> ValueSome) (ValueSome 5)) \ No newline at end of file From 94d148c9a69c9f633e88a8587c2b2aad1843bee6 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Fri, 12 Oct 2018 12:50:19 -0700 Subject: [PATCH 2/8] Undo removal of compilationrepresentation suffix and update surface area --- .../FSharp.Compiler.Private/FSComp.fs | 4 +- .../FSharp.Compiler.Private/FSComp.resx | 8 ++-- src/fsharp/FSharp.Core/option.fsi | 2 + .../SurfaceArea.net40.fs | 37 +++++++++++++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index f6fc5a409ea..23e20f9e770 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -3190,10 +3190,10 @@ type internal SR private() = /// This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation /// (Originally from ..\FSComp.txt:1042) static member tastInvalidAddressOfMutableAcrossAssemblyBoundary() = (1188, GetStringFunc("tastInvalidAddressOfMutableAcrossAssemblyBoundary",",,,") ) - /// Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" + /// 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:1043) static member parsNonAdjacentTypars() = (1189, GetStringFunc("parsNonAdjacentTypars",",,,") ) - /// Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" + /// 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:1044) static member parsNonAdjacentTyargs() = (1190, GetStringFunc("parsNonAdjacentTyargs",",,,") ) /// The use of the type syntax 'int C' and 'C ' is not permitted here. Consider adjusting this type to be written in the form 'C' diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index a56052a1e9d..edc9a7bff8f 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -3082,7 +3082,7 @@ This number is outside the allowable range for 32-bit floats - This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1us (uint16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). + This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). This is not a valid byte literal @@ -3193,10 +3193,10 @@ This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation - Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" + 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. - Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" + 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. 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>' @@ -4360,4 +4360,4 @@ This type does not inherit Attribute, it will not work correctly with other .NET languages. - + \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/option.fsi b/src/fsharp/FSharp.Core/option.fsi index beb8dafe04d..739484ae8cf 100644 --- a/src/fsharp/FSharp.Core/option.fsi +++ b/src/fsharp/FSharp.Core/option.fsi @@ -6,6 +6,8 @@ open System open Microsoft.FSharp.Core open Microsoft.FSharp.Collections + +[] /// Basic operations on options. module Option = /// Returns true if the option is not None. diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index fb3d061f045..0e8b6ea4b73 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -2269,6 +2269,13 @@ Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Item Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Value Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Item() Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Value() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsNone +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsSome +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsNone() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsSome() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] None +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] Some(T) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_None() Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object) Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode() Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]() @@ -2867,6 +2874,36 @@ Microsoft.FSharp.Core.OptionModule: TState FoldBack[T,TState](Microsoft.FSharp.C Microsoft.FSharp.Core.OptionModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpOption`1[T]) Microsoft.FSharp.Core.OptionModule: T[] ToArray[T](Microsoft.FSharp.Core.FSharpOption`1[T]) Microsoft.FSharp.Core.OptionModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean Equals(System.Object) +Microsoft.FSharp.Core.ValueOption: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Int32 Count[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Int32 GetHashCode() +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpValueOption`1[TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2], Microsoft.FSharp.Core.FSharpValueOption`1[T3]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpValueOption`1[Microsoft.FSharp.Core.FSharpValueOption`1[T]]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfNullable[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfObj[T](T) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpValueOption`1[T]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: System.String ToString() +Microsoft.FSharp.Core.ValueOption: System.Type GetType() +Microsoft.FSharp.Core.ValueOption: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T GetValue[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T ToObj[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpValueOption`1[T], TState) +Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.OptionalArgumentAttribute: Boolean Equals(System.Object) Microsoft.FSharp.Core.OptionalArgumentAttribute: Boolean IsDefaultAttribute() Microsoft.FSharp.Core.OptionalArgumentAttribute: Boolean Match(System.Object) From ee5797846830c28722e572f3a244942ef6d804eb Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Fri, 12 Oct 2018 12:52:27 -0700 Subject: [PATCH 3/8] Whoopise, add the suffix to the impl file --- src/fsharp/FSharp.Core/option.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsharp/FSharp.Core/option.fs b/src/fsharp/FSharp.Core/option.fs index 3744d0a7ade..552d1c9231f 100644 --- a/src/fsharp/FSharp.Core/option.fs +++ b/src/fsharp/FSharp.Core/option.fs @@ -4,6 +4,7 @@ namespace Microsoft.FSharp.Core open Microsoft.FSharp.Core.Operators +[] module Option = [] From cb0d6ba42f02b6d21652f8e689320f76ac5bbd61 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Fri, 12 Oct 2018 13:44:22 -0700 Subject: [PATCH 4/8] Update coreclr surface area --- .../SurfaceArea.coreclr.fs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index 841b5092f23..21f5fd6bc45 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -2189,6 +2189,13 @@ Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Item Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Value Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Item() Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Value() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsNone +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsSome +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsNone() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsSome() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] None +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] Some(T) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_None() Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object) Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode() Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]() @@ -2759,6 +2766,36 @@ Microsoft.FSharp.Core.OptionModule: TState FoldBack[T,TState](Microsoft.FSharp.C Microsoft.FSharp.Core.OptionModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpOption`1[T]) Microsoft.FSharp.Core.OptionModule: T[] ToArray[T](Microsoft.FSharp.Core.FSharpOption`1[T]) Microsoft.FSharp.Core.OptionModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean Equals(System.Object) +Microsoft.FSharp.Core.ValueOption: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Int32 Count[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Int32 GetHashCode() +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpValueOption`1[TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2], Microsoft.FSharp.Core.FSharpValueOption`1[T3]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpValueOption`1[Microsoft.FSharp.Core.FSharpValueOption`1[T]]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfNullable[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfObj[T](T) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpValueOption`1[T]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: System.String ToString() +Microsoft.FSharp.Core.ValueOption: System.Type GetType() +Microsoft.FSharp.Core.ValueOption: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T GetValue[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T ToObj[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpValueOption`1[T], TState) +Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.OptionalArgumentAttribute: Boolean Equals(System.Object) Microsoft.FSharp.Core.OptionalArgumentAttribute: Boolean Match(System.Object) Microsoft.FSharp.Core.OptionalArgumentAttribute: Int32 GetHashCode() From 09b6017cb8fa9e1cd838b711d7532e7b955a27aa Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Fri, 12 Oct 2018 15:53:46 -0700 Subject: [PATCH 5/8] Revert the FSComp changes that somehow got picked up --- src/buildfromsource/FSharp.Compiler.Private/FSComp.fs | 4 ++-- src/buildfromsource/FSharp.Compiler.Private/FSComp.resx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index 23e20f9e770..f6fc5a409ea 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -3190,10 +3190,10 @@ type internal SR private() = /// This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation /// (Originally from ..\FSComp.txt:1042) 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. + /// Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" /// (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. + /// Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" /// (Originally from ..\FSComp.txt:1044) static member parsNonAdjacentTyargs() = (1190, GetStringFunc("parsNonAdjacentTyargs",",,,") ) /// The use of the type syntax 'int C' and 'C ' is not permitted here. Consider adjusting this type to be written in the form 'C' diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index edc9a7bff8f..fcb03fb3982 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -3082,7 +3082,7 @@ This number is outside the allowable range for 32-bit floats - This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). + This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1us (uint16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). This is not a valid byte literal @@ -3193,10 +3193,10 @@ This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation - 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. + Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" - 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. + Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" 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>' From 444ef5c9ea4dec5dd812f6e8e511b6b0749bdad9 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Fri, 12 Oct 2018 15:54:42 -0700 Subject: [PATCH 6/8] newline --- src/buildfromsource/FSharp.Compiler.Private/FSComp.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index fcb03fb3982..a56052a1e9d 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4360,4 +4360,4 @@ This type does not inherit Attribute, it will not work correctly with other .NET languages. - \ No newline at end of file + From f364e540816e510818e228af58f44a7206c20c33 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Mon, 29 Oct 2018 14:32:28 -0700 Subject: [PATCH 7/8] Consume internal VOption module functions --- src/absil/illib.fs | 8 +++++++- .../FSharp.Compiler.Private/FSComp.fs | 4 ++-- .../FSharp.Compiler.Private/FSComp.resx | 8 ++++---- src/fsharp/NameResolution.fs | 2 +- src/fsharp/Optimizer.fs | 2 +- src/fsharp/QuotationTranslator.fs | 2 +- src/fsharp/symbols/Symbols.fs | 16 ++++++++-------- src/fsharp/tast.fs | 6 +++--- 8 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index 3d95265f651..69b0030f910 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -432,8 +432,14 @@ 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))) -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 + let inline isNone x = match x with ValueSome _ -> false | ValueNone -> true type String with member inline x.StartsWithOrdinal(value) = diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index f6fc5a409ea..23e20f9e770 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -3190,10 +3190,10 @@ type internal SR private() = /// This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation /// (Originally from ..\FSComp.txt:1042) static member tastInvalidAddressOfMutableAcrossAssemblyBoundary() = (1188, GetStringFunc("tastInvalidAddressOfMutableAcrossAssemblyBoundary",",,,") ) - /// Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" + /// 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:1043) static member parsNonAdjacentTypars() = (1189, GetStringFunc("parsNonAdjacentTypars",",,,") ) - /// Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" + /// 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:1044) static member parsNonAdjacentTyargs() = (1190, GetStringFunc("parsNonAdjacentTyargs",",,,") ) /// The use of the type syntax 'int C' and 'C ' is not permitted here. Consider adjusting this type to be written in the form 'C' diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index a56052a1e9d..edc9a7bff8f 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -3082,7 +3082,7 @@ This number is outside the allowable range for 32-bit floats - This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1us (uint16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). + This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). This is not a valid byte literal @@ -3193,10 +3193,10 @@ This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation - Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" + 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. - Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" + 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. 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>' @@ -4360,4 +4360,4 @@ This type does not inherit Attribute, it will not work correctly with other .NET languages. - + \ No newline at end of file diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 28e6830c8eb..060677b721f 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1096,7 +1096,7 @@ let AddEntityForProvidedType (amap: Import.ImportMap, modref: ModuleOrNamespaceR let tycon = Construct.NewProvidedTycon(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) modref.ModuleOrNamespaceType.AddProvidedTypeEntity(tycon) let tcref = modref.NestedTyconRef tycon - System.Diagnostics.Debug.Assert(ValueOption.isSome modref.TryDeref) + System.Diagnostics.Debug.Assert(ValueOptionInternal.isSome modref.TryDeref) tcref diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 043e9e4747f..777166611f8 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -3092,7 +3092,7 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) = | None -> false | Some mbrTyconRef -> // Check we can deref system_MarshalByRefObject_tcref. When compiling against the Silverlight mscorlib we can't - if ValueOption.isSome mbrTyconRef.TryDeref then + if ValueOptionInternal.isSome mbrTyconRef.TryDeref then // Check if this is a subtype of MarshalByRefObject assert (cenv.g.system_MarshalByRefObject_ty.IsSome) ExistsSameHeadTypeInHierarchy cenv.g cenv.amap vref.Range (generalizedTyconRef tcref) cenv.g.system_MarshalByRefObject_ty.Value diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs index d37be61d8d8..449cf00ed48 100644 --- a/src/fsharp/QuotationTranslator.fs +++ b/src/fsharp/QuotationTranslator.fs @@ -66,7 +66,7 @@ type QuotationGenerationScope = static member ComputeQuotationFormat g = let deserializeExValRef = ValRefForIntrinsic g.deserialize_quoted_FSharp_40_plus_info - if ValueOption.isSome deserializeExValRef.TryDeref then + if ValueOptionInternal.isSome deserializeExValRef.TryDeref then QuotationSerializationFormat.FSharp_40_Plus else QuotationSerializationFormat.FSharp_20_Plus diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs index 0df99aa034a..fcae4aca43c 100644 --- a/src/fsharp/symbols/Symbols.fs +++ b/src/fsharp/symbols/Symbols.fs @@ -86,7 +86,7 @@ module Impl = let entityIsUnresolved(entity:EntityRef) = match entity with | ERefNonLocal(NonLocalEntityRef(ccu, _)) -> - ccu.IsUnresolvedReference && ValueOption.isNone entity.TryDeref + ccu.IsUnresolvedReference && ValueOptionInternal.isNone entity.TryDeref | _ -> false let checkEntityIsResolved(entity:EntityRef) = @@ -754,10 +754,10 @@ and FSharpUnionCase(cenv, v: UnionCaseRef) = let isUnresolved() = - entityIsUnresolved v.TyconRef || ValueOption.isNone v.TryUnionCase + entityIsUnresolved v.TyconRef || ValueOptionInternal.isNone v.TryUnionCase let checkIsResolved() = checkEntityIsResolved v.TyconRef - if ValueOption.isNone v.TryUnionCase then + if ValueOptionInternal.isNone v.TryUnionCase then invalidOp (sprintf "The union case '%s' could not be found in the target type" v.CaseName) member __.IsUnresolved = @@ -854,18 +854,18 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = let isUnresolved() = entityIsUnresolved d.DeclaringTyconRef || match d with - | RecdOrClass v -> ValueOption.isNone v.TryRecdField - | Union (v, _) -> ValueOption.isNone v.TryUnionCase + | RecdOrClass v -> ValueOptionInternal.isNone v.TryRecdField + | Union (v, _) -> ValueOptionInternal.isNone v.TryUnionCase | ILField _ -> false let checkIsResolved() = checkEntityIsResolved d.DeclaringTyconRef match d with | RecdOrClass v -> - if ValueOption.isNone v.TryRecdField then + if ValueOptionInternal.isNone v.TryRecdField then invalidOp (sprintf "The record field '%s' could not be found in the target type" v.FieldName) | Union (v, _) -> - if ValueOption.isNone v.TryUnionCase then + if ValueOptionInternal.isNone v.TryUnionCase then invalidOp (sprintf "The union case '%s' could not be found in the target type" v.CaseName) | ILField _ -> () @@ -1331,7 +1331,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = let isUnresolved() = match fsharpInfo() with | None -> false - | Some v -> ValueOption.isNone v.TryDeref + | Some v -> ValueOptionInternal.isNone v.TryDeref let checkIsResolved() = if isUnresolved() then diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index d03c0114dc7..63cb1fbea4f 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -1901,7 +1901,7 @@ and [] |> List.tryFind (fun v -> match key.TypeForLinkage with | None -> true | Some keyTy -> ccu.MemberSignatureEquality(keyTy,v.Type)) - |> ValueOption.ofOption + |> ValueOptionInternal.ofOption /// Get a table of values indexed by logical name member mtyp.AllValsByLogicalName = @@ -3811,7 +3811,7 @@ and | None -> error(InternalError(sprintf "union case %s not found in type %s" x.CaseName x.TyconRef.LogicalName, x.TyconRef.Range)) /// Try to dereference the reference - member x.TryUnionCase = x.TyconRef.TryDeref |> ValueOption.bind (fun tcref -> tcref.GetUnionCaseByName x.CaseName |> ValueOption.ofOption) + member x.TryUnionCase = x.TyconRef.TryDeref |> ValueOptionInternal.bind (fun tcref -> tcref.GetUnionCaseByName x.CaseName |> ValueOptionInternal.ofOption) /// Get the attributes associated with the union case member x.Attribs = x.UnionCase.Attribs @@ -3870,7 +3870,7 @@ and | None -> error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) /// Try to dereference the reference - member x.TryRecdField = x.TyconRef.TryDeref |> ValueOption.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOption.ofOption) + member x.TryRecdField = x.TyconRef.TryDeref |> ValueOption.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOptionInternal.ofOption) /// Get the attributes associated with the compiled property of the record field member x.PropertyAttribs = x.RecdField.PropertyAttribs From e8eefa9812bda194050d934dfaf5ca9e59458cc0 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Mon, 29 Oct 2018 14:54:44 -0700 Subject: [PATCH 8/8] More internal voption module functions --- src/fsharp/tast.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 63cb1fbea4f..eea8833509c 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -3260,7 +3260,7 @@ and ValueSome tcr.binding /// Is the destination assembly available? - member tcr.CanDeref = ValueOption.isSome tcr.TryDeref + member tcr.CanDeref = ValueOptionInternal.isSome tcr.TryDeref /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. member x.CompiledRepresentation = x.Deref.CompiledRepresentation @@ -3870,7 +3870,7 @@ and | None -> error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) /// Try to dereference the reference - member x.TryRecdField = x.TyconRef.TryDeref |> ValueOption.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOptionInternal.ofOption) + member x.TryRecdField = x.TyconRef.TryDeref |> ValueOptionInternal.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOptionInternal.ofOption) /// Get the attributes associated with the compiled property of the record field member x.PropertyAttribs = x.RecdField.PropertyAttribs