TypeNum 0.3.0

dotnet add package TypeNum --version 0.3.0
NuGet\Install-Package TypeNum -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="TypeNum" Version="0.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add TypeNum --version 0.3.0
#r "nuget: TypeNum, 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.
// Install TypeNum as a Cake Addin
#addin nuget:?package=TypeNum&version=0.3.0

// Install TypeNum as a Cake Tool
#tool nuget:?package=TypeNum&version=0.3.0

TypeNum

Type-level integers for C#

NuGet Build Status

Example

class Tensor<NCols, NRows>
    where NCols : struct, INumeral
    where NRows : struct, INumeral
{
    public static int ColumnCount { get; } = NCols.Num;
    public static int RowCount { get; } = NRows.Num;

    internal readonly float[,] values = new float[ColumnCount, RowCount];

    public void Add(Tensor<NCols, NRows> tensor)
    {
        for (int col = 0; col < ColumnCount; col++)
            for (int row = 0; row < RowCount; row++)
                this.values[col, row] += tensor.values[col, row];
    }
}

Shorthands

For non-power-of-two numerals it is useful to add shorthands. Unfortunately declaring one is rather verbose in C#:

using N39 = TypeNum.Sum<TypeNum.Sum<TypeNum.Sum<
			TypeNum.N32,
			TypeNum.N4>,
			TypeNum.N2>,
			TypeNum.N1>;

...

Debug.Assert(N39.Num == 39);
var thirtyNine = new Tensor<N39, N39>();

Consistency

Technically, Sum<N1, N0> and Sum<N0, N1> represent the same numeral. However, there is no way to express it in C# type system. To alleviate that TypeNum tries to enforce one and only way to represent specific number.

To take advantage of that enforcement, avoid declaring your own implementations of the Numeral interface, and stick to N*, Twice<T>, and Sum<T1, T2> classes. They enforce several rules at run time (and, potentially, compile time in the future):

Twice

In Twice<T> T can only be one of the following:

  • the largest predefined type numeral (currently N4096)
  • another Twice<*>

So Twice<T> can only be used to represent very large numerals

Sum

The following rules are enforced on parameters T1 and T2 of Sum<T1, T2>:

  • T1.Num must be strictly greater (>) than T2.Num (swap them, if yours are opposite)
  • T2 can never be another Sum<*,*>. Replace any Sum<A, Sum<B, C>> with Sum<Sum<A, B>, C>
  • if T1 itself is a Sum<A, B>, then in Sum<Sum<A, B>, C> A and B must each be strictly greater (>) than C

Following these rules will ensure, that equal type numerals are always represented by identical types.

F# Example

In F# (unlike C#) operators can introduce new generic type parameters, which enables defining statically-typed matrix multiplication as an operator:

type Matrix<'rows, 'cols>() =
    static member ( * )(left: Matrix<'rows, 'cols>, right: Matrix<'cols, 'ncols>) =
        Matrix<'rows, 'ncols>()

module private Test =
    open TypeNum

    type N3 = Sum<N2, N1>
    type N7 = Sum<N4, N3>
    type N5 = Sum<N4, N1>

    let a = Matrix<N7, N5>()
    let b = Matrix<N5, N3>()
    let product = a * b

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
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 TypeNum:

Package Downloads
Small

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.3.0 225 2/16/2023
0.2.0 93 1/13/2024
0.2.0-CI-20210909-064812 219 9/9/2021
0.1.0-CI-20200206-090900 355 2/6/2020