QuickData.Core.FSharp 0.2.1

dotnet add package QuickData.Core.FSharp --version 0.2.1
                    
NuGet\Install-Package QuickData.Core.FSharp -Version 0.2.1
                    
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.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="QuickData.Core.FSharp" Version="0.2.1" />
                    
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.2.1
                    
#r "nuget: QuickData.Core.FSharp, 0.2.1"
                    
#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.2.1
                    
#: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.2.1
                    
Install as a Cake Addin
#tool nuget:?package=QuickData.Core.FSharp&version=0.2.1
                    
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);
  • 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.

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 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 

DenormalisationRange

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

A DenormalisationRange can be one of two kinds:

  • LowAndHighValues : Where two different values were used to create it;
  • SingleValue : Where the same value was used twice to create it.

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

  • fromFloats : The only way you can create a DenormalisationRange;
  • lowValue : Returns the lowest (float) value of the range;
  • highValue : Returns the highest (float) value of the range;
  • 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 (SingleValue) then that single value will always be returned by denormalisation, because there's no 'range' to be mapped to.

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

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 kinds:

  • 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

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']

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;
  • seqAsString : Returns a string containing the characters from the source sequence;
  • removeControlCharactersFromSeq : Returns a sequence 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 things which might be useful, including:

  • removeControlCharacters : Returns a string which contains no control characters;
  • rev : Returns a string which contains the characters in the original string reversed;
  • |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"

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"]

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 (1)

Showing the top 1 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.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.1 120 4/22/2026
0.2.0 115 4/22/2026
0.1.0 129 4/2/2026

See the Project URL repo for the release notes.