QuickData.Core.FSharp 0.3.0

dotnet add package QuickData.Core.FSharp --version 0.3.0
                    
NuGet\Install-Package QuickData.Core.FSharp -Version 0.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="QuickData.Core.FSharp" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="QuickData.Core.FSharp" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="QuickData.Core.FSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add QuickData.Core.FSharp --version 0.3.0
                    
#r "nuget: QuickData.Core.FSharp, 0.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package QuickData.Core.FSharp@0.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=QuickData.Core.FSharp&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=QuickData.Core.FSharp&version=0.3.0
                    
Install as a Cake Tool

QuickData.Core.FSharp

Contents

You can visit the QuickData.FSharp GitHub repository to report issues, ask questions, or make suggestions. You can also read about the changes across different versions in the release notes there.

Overview

This QuickData.Core.FSharp package contains the QuickData.FSharp namespace for F# developers which provides some types and their related functions, and also some helper functions.

Note: Most of the types in this package aren't particularly useful by themselves, as they are designed to be used only with other QuickData.FSharp packages, but you might find some use for them.

The types provided are:

  • Normal : Is a value which is clamped inside the range of 0.0 to +1.0 (inclusive);
  • NormalisationRange : Allows conversion of a float value to a Normal within a provided range of values;
  • DenormalisationRange : Allows conversion of a Normal to a float value within a provided range of values;
  • Variance : Is a value which is clamped inside the range of -1.0 to +1.0 (inclusive);
  • ExpansionRange : Allows conversion of a Variance to a float value within a provided range of values;
  • Digit : Is a representation of an integer between 0 and 9 (inclusive).

Important: DenormalisationRange and ExpansionRange work differently, see below.

Note: You can use IntelliSense in your code editor to get more information about each type and function.

Normals, Normalisation and Denormalisation

Normal

The Normal type is a value which is clamped inside the range of 0.0 to +1.0 (inclusive).

The Normal module provides functions for working with a Normal, including:

  • fromFloat : The only way you can manually create a Normal;
  • toFloat : Returns the value of a Normal as a float (equivalent to the Value method);
  • add : Adds two Normals together (equivalent to the + operator);
  • subtract : Subtracts one Normal from another Normal (equivalent to the - operator);
  • multiplyBy : Multiplies one Normal by another Normal (equivalent to the * operator);
  • divideBy : Divides one Normal by another Normal (equivalent to the / operator);
  • scale : Scales one Normal by another Normal (equivalent to the multiplyBy function);
  • invert : Creates a new Normal which is an inversion of the original;
  • flattenDown : Creates a new Normal which is the lower of the original and a provided level;
  • flattenUp : Creates a new Normal which is the higher of the original and a provided level;
  • fromBoolean : Creates a new Normal from a bool;
  • toBoolean : Creates a bool from a Normal.

Various values are also provided for convenience, for example Normal.minimum has an inner value of 0.0, Normal.oneHalf has an inner value of +0.5, and Normal.maximum has an inner value of +1.0.

The +, -, *, and / operators allow you to perform basic mathematical operations with Normals, each creating a new Normal in the process.

Inverting a Normal takes the value of the original, subtracts that from +1.0, and then creates a new Normal from that new value.

Note: When a Normal is printed via structured formatting - e.g. printf "%A" - the value will be prefixed with a 'N', e.g. N0.5. You would not usually print a Normal but this might be useful to know.

Normal Code Examples
let okay = Normal.fromFloat 0.85 // -> Normal 0.85 

let tooLow = Normal.fromFloat -0.5 // -> Normal 0.0 

let tooHigh = Normal.fromFloat 1.2 // -> Normal 1.0 

let value = Normal.oneTenth |> Normal.toFloat // -> float 0.1 

let added = Normal.fromFloat 0.4 + Normal.fromFloat 0.3 // Normal 0.7 

let subtracted = 
    Normal.fromFloat 0.9 
    |> Normal.subtract (Normal.fromFloat 0.5) // Normal 0.4 

let invertedNormal = Normal.fromFloat 0.7 |> Normal.invert // -> Normal 0.3 

Normalisation Range

The NormalisationRange type defines a range to be used to create a Normal from a float (see below).

A NormalisationRange can be one of two cases:

  • BetweenLowAndHigh : Where two different values were used to create it (the usual way to do it);
  • ToMinimumOnly : Where the same value was used twice to create it (not usually recommended).

The NormalisationRange module provides functions for working with a NormalisationRange, including:

  • fromFloats : Creates a NormalisationRange from the two (preferably different) provided float values;
  • fromCollection : Creates a NormalisationRange from the minimum/maximum float values in the provided collection;
  • lowValue : Returns an Option containing the lowest (float) value of the range (or None for ToMinimumOnly);
  • highValue : Returns an Option containing the highest (float) value of the range (or None for ToMinimumOnly);
  • normalise : Returns a Normal which is calculated from a float and the provided range.

The normalise process works by taking the value of the float and mapping it, via the provided normalisation range, to the Normal range (0.0 to +1.0).

For example, with a NormalisationRange of 0.0 to +200.0 (BetweenLowAndHigh), normalising a float of +150.0 would return a Normal of 0.75.

If both values used to create the range were the same then a ToMinimumOnly range will be created and normalisation will always return Normal.minimum, because there's no 'range' to be mapped to.

When creating a normalisation range from a collection, if the collection contains fewer than two elements then a ToMinimumOnly range will be created and normalisation will always return Normal.minimum, because there's no 'range' to be mapped to.

Normalisation Range Code Examples
let basicRange = 
    NormalisationRange.fromFloats 0.0 200.0 
    // -> BetweenLowAndHigh (0.0, 200.0)

let normal = NormalisationRange.normalise basicRange 100.0 // Normal 0.5 

let fromSequence = 
    seq { 10.0; 20.0; 5.0; 30.0; 45.0; 15.0 } 
    |> NormalisationRange.fromCollection 
    // -> BetweenLowAndHigh (5.0, 45.0)

let lowValue = fromSequence |> NormalisationRange.lowValue // -> 5.0 

DenormalisationRange

The DenormalisationRange type defines a range to be used to denormalise a Normal (see below).

A DenormalisationRange can be one of three cases:

  • LowAndHighValues : Where two different values were used to create it (the usual way to do it);
  • SingleValue : Where the same value was used twice to create it (might be useful in some circumstances);
  • NoDenormalisation : Where both values used to create it were zero (maybe not of much use but it's there if needed).

The DenormalisationRange module provides functions for working with a DenormalisationRange, including:

  • fromFloats : The only way you can create a DenormalisationRange;
  • lowValue : Returns an Option containing the lowest (float) value of the range (or None for NoDenormalisation);
  • highValue : Returns an Option containing the highest (float) value of the range (or None for NoDenormalisation);
  • denormalise : Returns a float value which is calculated from a Normal and the provided range.

The denormalise process works by taking the value of the Normal and mapping it from the Normal range (0.0 to +1.0) to the provided denormalisation range.

For example, with a DenormalisationRange of -100.0 to +100.0 (LowAndHighValues), denormalising a Normal of +0.75 would return a value of +50.0 (plus fifty), whereas denormalising a Normal of +0.25 with the same range would return a value of -50.0 (minus fifty).

If both values used to create the range were the same then a SingleValue range will be created and a single value will always be returned by denormalisation, because there's no 'range' to be mapped to.

However, if both values used to create the range were zero then a NoDenormalisation range will be created and the result of denormalisation will always be the original value.

DenormalisationRange Code Examples
let zeroToHundredRange = DenormalisationRange.fromFloats 0.0 100.0 

let a = 
    Normal.oneQuarter 
    |> DenormalisationRange.denormalise zeroToHundredRange // -> float 25.0
let b = 
    Normal.twoFifths 
    |> DenormalisationRange.denormalise zeroToHundredRange // -> float 40.0

let spanZeroRange = DenormalisationRange.fromFloats -200.0 100.0 

let x = 
    Normal.twoThirds 
    |> DenormalisationRange.denormalise spanZeroRange // -> float 0.0 
let y = 
    Normal.oneFifth 
    |> DenormalisationRange.denormalise spanZeroRange // -> float -140.0

let noDenormalisation = DenormalisationRange.fromFloats 0.0 0.0 

let z = 
    Normal.oneHalf 
    |> DenormalisationRange.denormalise noDenormalisation // -> float 0.0 

Variances and Expansion

Variance

The Variance type is a value which is clamped inside the range of -1.0 to +1.0 (inclusive).

The Variance module provides functions for working with Variance values, including:

  • fromFloat : The only way you can manually create a Variance;
  • toFloat : Returns the value of a Variance as a float (equivalent to the Value method);
  • invert : Creates a new Variance which is an inversion of the original;
  • fromNormal : Creates a new Variance directly from the value of a Normal;
  • fromNormalSpread : Creates a new Variance from the value of a Normal (value is recalculated);
  • toNormal : Creates a new Normal directly from the value of a Variance;
  • toNormalSpread : Creates a new Normal from the value of a Variance (value is recalculated).

Various values are also provided for convenience, for example Variance.minimum has an inner value of -1.0, Variance.zero has an inner value of 0.0, and Variance.maximum has an inner value of +1.0.

The * operator allows you to multiply a Variance by another Variance, or multiply a Variance by a Normal, to give a new Variance.

Inverting a Variance takes the value of the original, gets the negative of that value (producing a positive if the original value was negative), and then creates a new Variance from that new value.

Note: When a Variance is printed via structured formatting - e.g. printf "%A" - the value will be prefixed with a 'V', e.g. V0.5. You would not usually print a Variance but this might be useful to know.

Variance Code Examples
let okayPositive = Variance.fromFloat 0.7 // -> Variance 0.7 

let okayNegative = Variance.fromFloat -0.3 // -> Variance -0.3 

let invertedVariance = 
    Variance.fromFloat 0.4 
    |> Variance.invert // -> Variance -0.4 

let ofNormal = 
    Normal.fromFloat 0.2 
    |> Variance.fromNormal // -> Variance 0.2 

let ofNormalSpread = 
    Normal.fromFloat 0.2 
    |> Variance.fromNormalSpread // -> Variance -0.6

ExpansionRange

The ExpansionRange type defines a range to be used to expand a Variance (see below).

An ExpansionRange can be one of three cases:

  • AsymmetricalExpansion : Where two different values were used to create it;
  • SymmetricalExpansion : Where only one value was used to create it (or the same value twice);
  • NoExpansion : Where the only value used to create it was 0.0.

The ExpansionRange module provides functions for working with an ExpansionRange, including:

  • fromFloats : The way you can create an ExpansionRange with two values (Symmetrical or Asymmetrical expansion, depending on the input values);
  • fromSingleFloat : The way you can create an ExpansionRange with only one value (Symmetrical expansion only);
  • negativeMagnitude : Returns an Option containing the negative magnitude (if there is one);
  • positiveMagnitude : Returns an Option containing the positive magnitude (if there is one);
  • expand : Returns a float value which is calculated from a Variance and the provided range.

The expand process works by taking the value of a Variance and multiplying it by one of the magnitudes in the ExpansionRange.

For example, with an ExpansionRange of -100.0 to +300.0 (AsymmetricalExpansion), expanding a Variance of +0.5 would return a value of +150.0 (+300.0 * +0.5), whereas expanding a Variance of -0.5 with the same range would return a value of -50.0 (-0.5 * abs(-100.0)).

If only one unique magnitude was provided when the range was created (SymmetricalExpansion) then the same magnitude is used for both positive and negative scaling. If the only magnitude that was provided when the range was created was 0.0 (NoExpansion) then the actual value of the Variance is always returned. (You can think of the NoExpansion range as an equivalent to the id function - value out = value in.)

ExpansionRange Code Examples
let symmetricalRange = ExpansionRange.fromSingleFloat 40 

let c = 
    Variance.fromFloat 0.5 
    |> ExpansionRange.expand symmetricalRange // -> float 20.0
let d = 
    Variance.fromFloat -0.5 
    |> ExpansionRange.expand symmetricalRange // -> float -20.0

let asymmetricalRange = ExpansionRange.fromFloats -50.0 100.0

let e = 
    Variance.fromFloat 0.5 
    |> ExpansionRange.expand asymmetricalRange // -> float 50.0
let f = 
    Variance.fromFloat -0.5 
    |> ExpansionRange.expand asymmetricalRange // -> float -25.0

let noExpansion = ExpansionRange.fromFloats 0.0 0.0 

let g = 
    Variance.fromFloat 0.5 
    |> ExpansionRange.expand noExpansion // -> float 0.5 
let h = 
    Variance.fromFloat -0.5 
    |> ExpansionRange.expand noExpansion // -> float -0.5

Digits

The Digit type is a discriminated union which contains cases, each of which relates to an integer value between 0 and 9 (inclusive).

These cases are: Zero, One, Two, Three, Four, Five, Six, Seven, Eight, and Nine (in that order).

The Digit module provides various functions for working with Digits, including:

  • allDigits : Returns a sequence containing all the possible Digits, from Zero to Nine (inclusive);
  • nonZeroDigits : Returns a sequence containing the Digits from One to Nine (inclusive);
  • toChar : Returns a char which relates to a Digit, e.g. Zero returns '0';
  • fromChar : Returns a Digit which relates to a numerical character, e.g. '0' returns Zero;
  • toInt : Returns an int which relates to a Digit, e.g. Zero returns 0;
  • fromInt : Returns a Digit which relates to an integer, e.g. 0 returns Zero;
  • previous : Returns the Digit which is one less than the original;
  • next : Returns the Digit which is one more than the original;
  • add : Returns the result of adding two Digits together;
  • subtract : Returns the result of subtracting one Digit from another Digit;
  • invert : Returns a new Digit which is the inversion of the original;
  • toString : Returns a string which is the lower-case 'name' of a Digit, e.g. Zero returns "zero";
  • toNormal : Returns a Normal which relates to a Digit, e.g. Zero returns Normal.minimum.

The following active patterns are also available:

  • |DigitIsZero|DigitIsNotZero| : Is the Digit a Zero or not?
  • |DigitIsEven|DigitIsOdd| : Is the Digit even or odd?
Digit Code Examples
let three = '3' |> Digit.fromChar // -> Three

let invalidChar 'x' |> Digit.fromChar // -> Raises an exception

let threeChar = three |> Digit.toChar // -> '3'

let threeValue = three |> Digit.toInt // -> 3

let threeName = three |> Digit.toString // -> "three"

let previous = three |> Digit.previous // -> Two 

let inverted = three |> Digit.invert // -> Six

Note: There's not a lot you can do with Digits by themselves and they are much more useful when used with the functionalities provided in the QuickData.Digits.FSharp package.

Helper Functions

MathHelpers

The MathHelpers module contains some functions which might be useful, including:

  • lowThenHigh : Returns a tuple where the two values provided are returned with the lowest value first;
  • clamp : Clamps a value to be inside the range provided;
  • round : Returns the value rounded to the provided number of decimal places;
  • toRadians : Calculates the radians value for a provided degrees value (this function may have an accuracy which is less than you need; you can use something else if you need better accuracy).

Note: These functions require that the MathHelpers module name be prefixed to the function name (just so they don't interfere with other functions with the same name).

MathHelpers Code Examples
let clamped = 45.0 |> MathHelpers.clamp 0.0 30.0 // -> 30.0

let lowFirst = MathHelpers.lowThenHigh 20.0 -40.0 // -> (-40.0, 20.0)

let rounded = 5.6753 |> MathHelpers.round 2 // -> 5.68 

SeqHelpers

The SeqHelpers module contains some functions which might be useful, including:

  • repeated : Returns a sequence where the provided element is repeated endlessly;
  • cycle : Returns a sequence where the provided sequence is repeated endlessly;
  • tombola : Returns a sequence where the provided sequence is shuffled endlessly via a random number generator.

Tip: These functions work with any type of element, not just those provided by this package.

SeqHelpers Code Examples
// Remember to take the number of elements which you need, 
//  otherwise you will get an infinite sequence.

let repeated = 
    "XYZ" 
    |> SeqHelpers.repeated 
    |> Seq.take 4 
    |> Seq.toList // -> ["XYZ"; "XYZ"; "XYZ"; "XYZ"]

let cycled = 
    seq { 1 ; 2 ; 3 } 
    |> SeqHelpers.cycle 
    |> Seq.take 8 
    |> Seq.toList // -> [1; 2; 3; 1; 2; 3; 1; 2]

let rng = System.Random.Shared 

let tombolad = 
    seq { 'a' ; 'b' ; 'c' } 
    |> SeqHelpers.tombola rng 
    |> Seq.take 8 
    |> Seq.toList // -> e.g. ['c'; 'b'; 'a'; 'a'; 'b'; 'c'; 'a'; 'c']

ListHelpers

The ListHelpers module contains some things which might be useful, including:

  • intersperse : Returns a new list where the same new element is inserted between the existing elements of a list.
ListHelpers Code Examples
let interspersed = 
    [ "one" ; "two" ; "three" ] 
    |> ListHelpers.intersperse "****"
    // -> [ "one" ; "****" ; "two" ; "****" ; "three" ] 

CharHelpers

The CharHelpers module contains some functions which might be useful, including:

  • replaceSpaceWith : Returns the replacement char if the original char is a space, otherwise return the original char;
  • arrayAsString : Returns a string containing the characters from the source array of characters;
  • seqAsString : Returns a string containing the characters from the source sequence of characters;
  • removeControlCharactersFromSeq : Returns a sequence of char which contains no control characters;
  • removeControlCharactersFromArray : Returns an array of char which contains no control characters.

None of these functions do anything 'fancy' but they can be convenient to use on occasion.

CharHelpers Code Examples
let asItWas = 'x' |> CharHelpers.replaceSpaceWith 'z' // -> 'x' 

let notSpace = ' ' |> CharHelpers.replaceSpaceWith 'a' // -> 'a' 

let stringFromArray = [| 't' ; 'e' ; 'x' ; 't' |] |> CharHelpers.arrayAsString // -> "text"

let stringFromSequence = seq { 't' ; 'e' ; 'x' ; 't' } |> CharHelpers.seqAsString // -> "text"

let withNoControlCharacters = 
    seq { '\a' ; 'x' ; '\r' ; 'y' } 
    |> CharHelpers.removeControlCharactersFromSeq // -> seq { 'x' ; 'y' }

StringHelpers

The StringHelpers module contains some functions which might be useful, including:

  • removeControlCharacters : Returns a string which contains no control characters;
  • removeSpaces : Returns a string which contains no spaces;
  • removeAllButNumerals : Returns a string which contains only numerals;
  • removeAllButLettersAndNumerals : Returns a string which contains only letters and numerals;
  • rev : Returns a string which contains the characters in the original string reversed;
  • capitalise : Returns a string which contains the characters in the original string with the first character converted to upper-case (if it's a letter);
  • joinedWith : Returns a string which contains the strings in the original sequence joined with the joiner string between each source string (some convenience functions are also available);
  • joinedVia : Returns a string which contains the strings in the source sequence with a joiner string between each element;
  • split : Returns an array of string which contains the parts of the original string split at the characters supplied.

The following active patterns are also available:

  • |StringIsEmpty|StringIsNotEmpty| : Is the string empty or only contains spaces?
  • |StringContainsControlCharacters|StringDoesNotContainControlCharacters| : Does the string contain control characters?
  • |StringOnlyContainsNumbers|StringContainsMoreThanJustNumbers| : Does the string only contain numbers?
  • |StringOnlyContainsLetters|StringContainsMoreThanJustLetters| : Does the string only contain letters (either upper- or lower-case)?
  • |StringStartsWithSpace|StringDoesNotStartWithSpace| : Does the string start with a space?
  • |StringEndsWithSpace|StringDoesNotEndWithSpace| : Does the string end with a space?
  • |StringIsLongerThan|_| : Is the string longer than expected/required?
  • |StringIsShorterThan|_| : Is the string shorter than expected/required?

None of these functions/patterns do anything 'fancy' but they can be convenient to use on occasion.

StringHelpers Code Examples
let withNoControlCharacters = 
    "\aNo\n Mess\r" 
    |> StringHelpers.removeControlCharacters // -> "No Mess"

let reversed = "abcd" |> StringHelpers.rev // -> "dcba"

let joined = 
    seq { "same" ; "join" ; "between" ; "strings" }
    |> StringHelpers.joinedWith "-" 
    // -> "same-join-between-strings"

let joinedVia = 
    seq { "different" ; "joiners" ; "between" ; "strings" }
    |> StringHelpers.joinedVia (seq { "-" ; "/" ; "=" })
    // -> "different-joiners/between=strings"

open QuickData.FSharp.StringHelpers 

// Active patterns can be used alone, for example:
let isEmpty = // -> "is empty"
    match "" with 
    | StringIsEmpty -> "is empty"
    | StringIsNotEmpty -> "not empty"

let tooLong = // -> "too long at 14 characters"
    match "my long string" with 
    | StringIsLongerThan 6 length -> "too long at " + length.ToString() + " characters"
    | _ -> "okay length"

//...or they can be used together for basic validation:
let results = 
    [ "" 
      "return\r"
      " starts with space" 
      "ends with space " 
      "too many characters" 
      "short" 
      "   "
      "this is okay"
      "\n\a\r"
      String.Empty ]
    |> List.map (fun str -> 
        match str with 
        | StringIsEmpty -> "string is empty"
        | StringContainsControlCharacters -> "contains control characters"
        | StringStartsWithSpace -> "starts with space"
        | StringEndsWithSpace -> "ends with space"
        | StringIsLongerThan 12 length -> "too long at " + length.ToString() + " characters"
        | StringIsShorterThan 6 length -> "too short at " + length.ToString() + " characters"
        | _ -> str)
    // -> ["string is empty"; "contains control characters"; "starts with space";
    //     "ends with space"; "too long at 19 characters";
    //     "too short at 5 characters"; "string is empty"; "this is okay";
    //     "contains control characters"; "string is empty"]

Exception-free Processing

In all of the QuickData.FSharp packages, some functions will raise an exception if the internal processing fails for some reason or if the input was not as expected.

Many of this type of function will also have alternative exception-free versions which do not raise an exception.

These alternative functions are:

  • <module-name>.FailSafe.<function-name> : Returns a default value, instead of raising an exception;
  • <module-name>.Option.<function-name> : Returns None instead of raising an exception, otherwise Some value;
  • <module-name>.Result.<function-name> : Returns Error <error-type> instead of raising an exception, otherwise Ok value.

Discriminated Union Identity Values

In all of the QuickData.FSharp packages, where a discriminated union exists to specify a parameter for a function, there often will be two functions related to that discriminated union which return an integer identity value from the union case - toInt - or return a union case from an integer identity value - fromInt.

These can be useful if you need to store a value in a data structure which does not cater for discriminated unions, e.g. in a file, in JSON, etc.

The toInt function will always return a valid identity value.

Notes:

  1. Where a fromInt function exists there often will be exception-free versions available.

  2. All valid identity values are in the range 100 to 999 (inclusive). Any value which has fewer, or more, than three digits can be immediately identified as being invalid, but not all three-digit values are valid. While identity values are unique within a discriminated union, some identity values may be shared by cases in different discriminated unions but no functional equality or relationship between the two should be inferred. Identity values will not change unless specifically mentioned in the release notes.

The defaultCase value (where available) contains the default case for that discriminated union.

The allCases value (where available) contains a list of all of the cases for the discriminated union.

Discriminated Union Identity Value Examples

let good = DigitZeroPolicy.fromInt 200 // -> DoNotAllowZeroValue
let bad = DigitZeroPolicy.fromInt 123 // Raises an exception

let goodFailSafe = DigitZeroPolicy.FailSafe.fromInt 300 // -> NoStartingZero
let badFailSafe = DigitZeroPolicy.FailSafe.fromInt 123 // -> AllowAnyDigit (default)

let goodOption = DigitZeroPolicy.Option.fromInt 400 // -> NoZeroesAtAll
let badOption = DigitZeroPolicy.Option.fromInt 123 // None

let goodResult = DigitZeroPolicy.Result.fromInt 100 // -> Ok AllowAnyDigit
let badResult = DigitZeroPolicy.Result.fromInt 123 // -> Error (InvalidArgumentError ("identity", "123"))

Dependencies

This package has no dependencies other than FSharp.Core which you will be using anyway.

Note: This package will normally be automatically installed if you install any other QuickData...FSharp package, so you normally don't need to manually install this package yourself.

Usage

The types and functions in this package have been designed to be used only with F#.

However, they may also be usable with C# but this has not been tested, so use them with C# at your own risk.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on QuickData.Core.FSharp:

Package Downloads
QuickData.Numbers.FSharp

This package for F# developers contains types and modules which allow developers to quickly create sequences of numerical data. This numerical data can be given different 'shapes' and modified in various ways to produce data for testing, or whenever a sequence of numbers is required. All of the sequences generated by the functions in this package are standard F# sequences, and all of the internal processing is done exclusively with standard F# sequences, so they give you all of the benefits of, and follow the same rules as, standard F# sequences. See the README for more information.

QuickData.Words.FSharp

This package for F# developers contains types and modules which allow developers to quickly create sequences of English words. All of the sequences generated by the functions in this package are standard F# sequences, and all of the internal processing is done exclusively with standard F# sequences, so they give you all of the benefits of, and follow the same rules as, standard F# sequences. See the README for more information.

QuickData.Characters.FSharp

This package for F# developers contains types and modules which allow developers to quickly create sequences of characters. All of the sequences generated by the functions in this package are standard F# sequences, and all of the internal processing is done exclusively with standard F# sequences, so they give you all of the benefits of, and follow the same rules as, standard F# sequences. See the README for more information.

QuickData.Digits.FSharp

This package for F# developers contains types and modules which allow developers to quickly create and manipulate sequences of digits. All of the sequences generated by the functions in this package are standard F# sequences, and all of the internal processing is done exclusively with standard F# sequences, so they give you all of the benefits of, and follow the same rules as, standard F# sequences. See the README for more information. Some functions create other types of collection.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 51 6/11/2026
0.2.1 123 4/22/2026
0.2.0 118 4/22/2026
0.1.0 134 4/2/2026

See the Project URL repo for the release notes.