QuickData.Digits.FSharp 0.3.0

dotnet add package QuickData.Digits.FSharp --version 0.3.0
                    
NuGet\Install-Package QuickData.Digits.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.Digits.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.Digits.FSharp" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="QuickData.Digits.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.Digits.FSharp --version 0.3.0
                    
#r "nuget: QuickData.Digits.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.Digits.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.Digits.FSharp&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=QuickData.Digits.FSharp&version=0.3.0
                    
Install as a Cake Tool

QuickData.Digits.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.Digits.FSharp package contains the QuickData.Digits.FSharp namespace for F# developers which provides some types, modules, and their related functions for building and manipulating sequences of Digit, and getting textual representations of them.

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. (Some functions create other types of collection.)

See the QuickData.Core.FSharp documentation for more information about the Digit and Normal types.

The types provided are:

  • DigitationPolicy : The ways in which a new sequence of Digit can be generated from a sequence of Normal;
  • DigitZeroPolicy : The ways in which a new sequence of random Digits can be generated;
  • DigitSpellPolicy : The ways in which a spelt number can be generated from a sequence of Digit via the Digit.Seq.spell function;
  • DigitSpellJoiner : The ways in which the words can be joined in the 'phrases' created by the Digit.Seq.spell function.

The modules provided are:

  • Digit.Seq : Create and manipulate a sequence of Digit;
  • DigitSpellJoiner : Contains functions for creating new joiners and getting the strings from them.

This package also extends the Digit module from QuickData.Core.FSharp by adding the Digit.spellDecimal function (see spelling below).

Digit Sequences

The Digit.Seq module provides functions for working with sequences of Digit.

Digit Sequence Conversion

Note: Only positive integers can be represented as a sequence of Digits.

A number of functions are available for the conversion of sequences from and to Digits, chars, ints, Normals and string.

For example, fromChars creates a new sequence of Digit from a sequence of char, and toInt creates a new single int from a sequence of Digit.

The fromString function is like the fromChars function but it ignores any non-numerical characters in the string and will not raise an exception.

Note: Some of these functions are available as exception-free versions, including:

  • fromChars - when one or more chars are not numerical, e.g. '0' to '9' (inclusive);
  • fromInts - when one or more ints are not in the range 0 to 9 (inclusive).
Digit Sequence Conversion Code Examples
let rng = System.Random 9831 // Randomly-chosen seed.

let randomInt = rng.Next() // -> 1480705143

// Some examples of conversion.
// There are others to discover and try for yourself.

let fromRandom = 
    randomInt 
    |> Digit.Seq.fromInt 
    // -> seq { One; Four; Eight; Zero; Seven; Zero; Five; One; Four; Three }

let toInts = 
    fromRandom |> Digit.Seq.toInts 
    // -> seq { 1; 4; 8; 0; 7; 0; 5; 1; 4; 3 }

let fromInts = 
    toInts |> Digit.Seq.fromInts 
    // -> seq { One; Four; Eight; Zero; Seven; Zero; Five; One; Four; Three }

let toChars = 
    fromInts |> Digit.Seq.toChars 
    // -> seq { '1'; '4'; '8'; '0'; '7'; '0'; '5'; '1'; '4'; '3' }

let toString = 
    fromInts 
    |> Digit.Seq.toString // -> "1480705143"

let fromString = 
    toString 
    |> Digit.Seq.fromString 
    // -> seq { One; Four; Eight; Zero; Seven; Zero; Five; One; Four; Three }

Digitation Policy

The DigitationPolicy type defines cases to be used when creating a sequence of Digit from a sequence of Normal with the fromNormals function.

The cases are, for when the Normal value is 'between' two Digits:

  • UseNearest : Map to the nearest Digit in the set (uses Math.Round internally and, for many uses, this will be adequate);
  • TendDownwards : Map to the lower of the two Digits (uses Math.Floor internally);
  • TendUpwards : Map to the higher of the two Digits (uses Math.Ceiling internally);
  • TendOutwards : Map to the Digit which is lower when the value is less then 0.5 or higher if greater than or equal to 0.5;
  • TendInwards : Map to the Digit which is higher when the value is less then 0.5 or lower if greater than or equal to 0.5.

The difference between these cases can sometimes be subtle so it is recommended that you experiment to see which is best for your particular requirements with the data you are processing.

Digit Sequence Variations

A number of functions are available for the variation of a sequence of Digit.

These include:

  • raising and lowering the values by a certain amount, e.g. raiseAll and lowerAll;
  • finding the previous (one less), or next (one more), Digit, e.g. previous and next;
  • inverting values, e.g. invert.
Digit Sequence Variations Code Examples
let original = seq { Zero ; Four ; Seven ; Nine }
let previous = original |> Digit.Seq.previous // -> seq { Nine ; Three ; Six ; Eight } 
let next = original |> Digit.Seq.next // -> seq { One ; Five ; Eight ; Zero } 
let inverted = original |> Digit.Seq.invert // -> seq { Nine ; Five ; Two ; Zero }
let raised = original |> Digit.Seq.raiseAll Two // -> seq { Two ; Six ; Nine ; One }

Digit Sequence Building

A number of functions are available for the building of a sequence of Digit, including:

  • randomAll and randomNonZero : Values generated via a random number generator;
  • randomViaPolicy : Values generated randomly according to the specified DigitZeroPolicy (see below);
  • randomised : Randomly chosen values from another sequence (with some convenience functions);
  • cycled : Endlessly cycled values from another sequence (with some convenience functions);
  • tombola : Endlessly shuffled values from another sequence (with some convenience functions).

Note: The functions which require a count parameter will produce a sequence of finite length.

Digit Zero Policy

The DigitZeroPolicy type defines cases to be used when creating a sequence of Digit with the randomViaPolicy function.

The cases are:

  • AllowAnyDigit : All Digits are allowed (this is equivalent to using the randomAll function);
  • DoNotAllowZeroValue : Do not allow the generated Digits to be all Zero;
  • NoStartingZero : Do not allow the first Digit to be Zero;
  • NoZeroesAtAll : Do not allow any Digit to be Zero (this is equivalent to using the randomNonZero function).
Digit Sequence Building Code Examples
let rng = System.Random 9831 // Randomly-chosen seed.

// Some examples of sequence building.
// There are others to discover and try for yourself.

let random = 
    Digit.Seq.randomAll rng 9 
    // -> seq { Four; Five; Nine; Seven; Eight; Seven; Five; Two; Four }

let randomViaPolicy = 
    [ for _ in 1..6 -> 
        Digit.Seq.randomViaPolicy rng DigitZeroPolicy.NoStartingZero 5 
        |> Digit.Seq.toString ]
    // -> [ "16904"; "74289"; "17441"; "62095"; "60544"; "85190" ]

let randomised = 
    seq { One ; Three ; Five } 
    |> Digit.Seq.randomised rng 7
    // -> seq { Five; One; Five; Five; One; Three; One }

let cycled = 
    seq { Two ; Four ; Six ; Eight } 
    |> Digit.Seq.cycled 
    |> Seq.take 7
    // -> seq { Two; Four; Six; Eight; Two; Four; Six }

Spelling

The Digit.spellDecimal function creates a string which is the spelt version of the input decimal value.

For example, the value 780206.531M becomes "seven hundred and eighty thousand, two hundred and six point five three one".

There are currently no modification prarameters for this function, but these might be added at a later point - check the release notes if you notice any differences.

Note: The spellDecimal function is also available as exception-free versions. (An exception has never been raised in testing but all possible decimal values have not been checked.)


The Digit.Seq.spell function creates a list of strings which are the 'phrases' produced when spelling the Digits in a sequence as text without numerals.

For example, the sequence seq { One; Two; Zero; Four; Five } could become:

  • ["one"; "two"; "oh"; "four"; "five"]
  • ["twelve"; "zero four"; "five"]
  • ["twelve"; "oh"; "fourty-five"]

...depending on the policy and joiner specified.

A phrase can be produced from one or more Digits, depending on the policy specified, so there can be fewer elements in the output list than there were Digits in the original sequence, as can be seen above.

Note: The only language available is English. There are no plans to support other languages.

Digit Spell Policy

The DigitSpellPolicy type defines cases to be used when creating a list of strings ('phrases') with the Digit.Seq.spell function.

The cases, which specify the types of phrases which can be created, are:

  • AsSingleDigitsZero : Each phrase contains only the word associated with the respective Digit, with Zero spelt as "zero";
  • AsSingleDigitsOh : Each phrase contains only the word associated with the respective Digit, with Zero spelt as "oh";
  • AsDoubleDigitsZero : Each phrase contains one or more words associated with the respective Digit pair, with Zero spelt as "zero";
  • AsDoubleDigitsOh : Each phrase contains one or more words associated with the respective Digit pair, with Zero spelt as "oh";
  • AsTelephoneBasic : Each phrase contains one or more words associated with one or more Digits, with Zero spelt as "oh".

For double digit spelling, pairs of Digits are taken from the start of the original sequence, working forward. If there is an odd number of Digits then the last Digit will be spelt individually.

Digit Spell Joiner

The DigitSpellJoiner type defines cases to be used when creating a list of strings ('phrases') with the Digit.Seq.spell function.

The cases, which specify how the words in the phrases are to be joined, are:

  • JoinedWithNothing : The phrase will have no joining character(s) between the words, e.g. "doublezero";
  • JoinedWithSpace : The phrase will have a single space between the words, e.g. "double zero";
  • JoinedWithComma : The phrase will have a single comma between the words, e.g. "double,zero";
  • JoinedWithDash : The phrase will have a single dash between the words, e.g. "double-zero";
  • JoinedWithDot : The phrase will have a single dot between the words, e.g. "double.zero";
  • JoinedWithSlash : The phrase will have a single slash between the words, e.g. "double/zero";
  • JoinedWithBackslash : The phrase will have a single backslash between the words, e.g. "double\zero";
  • JoinedWithCommaAndSpace : The phrase will have a single comma and then a single space between the words, e.g. "double, zero";
  • UserDefinedJoiner : The phrase will have a user-defined string between the words.

You can create new digit spell joiners via the DigitSpellJoiner.fromString function, and the string used in any joiner can be retrieved via the DigitSpellJoiner.toString' function.

Spelling Code Examples

let asSingleOhWithSpace = 
    seq { One; Two; Zero; Four; Five } 
    |> Digit.Seq.spell AsSingleDigitsOh JoinedWithSpace 
    // -> ["one"; "two"; "oh"; "four"; "five"]

let asDoubleZeroWithDash = 
    seq { One; Two; Zero; Four; Five } 
    |> Digit.Seq.spell AsDoubleDigitsZero JoinedWithDash
    // -> ["twelve"; "zero-four"; "five"]

let phoneNumber = 
    "(0800) 56-00-78"
    |> Digit.Seq.fromString 
    // -> seq { Zero; Eight; Zero; Zero; Five; Six; Zero; Zero; Seven; Eight }
    |> Digit.Seq.spell AsTelephoneBasic JoinedWithSpace 
    // -> [ "oh"; "eight hundred"; "fifty six"; "double oh"; "seventy eight" ]
    |> List.map StringHelpers.capitalise 
    // -> [ "Oh"; "Eight hundred"; "Fifty six"; "Double oh"; "Seventy eight" ]
    |> StringHelpers.joinedWithCommaAndSpace 
    // -> "Oh, Eight hundred, Fifty six, Double oh, Seventy eight"

Exception-free Processing

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.

For example, Digit.Seq.fromChars will raise an exception upon failure whereas Digit.Seq.Failsafe.fromChars will return a default value (in this case an empty sequence of Digit).

Discriminated Union Identity Values

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.

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

Note: 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 = DigitationPolicy.fromInt 200 // -> TendDownwards
let bad = DigitationPolicy.fromInt 123 // Raises an exception

let goodFailSafe = DigitationPolicy.FailSafe.fromInt 300 // -> TendUpwards
let badFailSafe = DigitationPolicy.FailSafe.fromInt 123 // -> UseNearest (default)

let goodOption = DigitationPolicy.Option.fromInt 400 // -> Some TendOutwards
let badOption = DigitationPolicy.Option.fromInt 123 // None

let goodResult = DigitationPolicy.Result.fromInt 500 // -> Ok TendInwards
let badResult = DigitationPolicy.Result.fromInt 123 // -> Error (InvalidArgumentError ("identity", "123"))

Dependencies

This package is dependent upon FSharp.Core which you will be using anyway, and the QuickData.Core.FSharp package which will normally be automatically installed if you install this package.

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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 39 6/11/2026

See the Project URL repo for the release notes.