{"id":19174994,"url":"https://github.com/losttech/typenum","last_synced_at":"2025-05-07T18:21:31.225Z","repository":{"id":65931480,"uuid":"176853949","full_name":"losttech/TypeNum","owner":"losttech","description":"Type-level integers for C#","archived":false,"fork":false,"pushed_at":"2024-01-12T00:33:26.000Z","size":50,"stargazers_count":11,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-20T01:33:02.419Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/losttech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-21T02:25:17.000Z","updated_at":"2023-09-27T20:13:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"fbd9c44e-3127-48dd-943d-b44ad47ed066","html_url":"https://github.com/losttech/TypeNum","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FTypeNum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FTypeNum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FTypeNum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FTypeNum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/losttech","download_url":"https://codeload.github.com/losttech/TypeNum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252931819,"owners_count":21827172,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T10:20:18.263Z","updated_at":"2025-05-07T18:21:31.202Z","avatar_url":"https://github.com/losttech.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TypeNum\nType-level integers for C#\n\n[![NuGet](https://img.shields.io/nuget/v/TypeNum.svg)](https://www.nuget.org/packages/TypeNum/)\n[![Build Status](https://losttech.visualstudio.com/TypeNum/_apis/build/status/losttech.TypeNum?branchName=master)](https://losttech.visualstudio.com/TypeNum/_build/latest?definitionId=29\u0026branchName=master)\n\n# Example\n```csharp\nclass Tensor\u003cNCols, NRows\u003e\n    where NCols : struct, INumeral\n    where NRows : struct, INumeral\n{\n    public static int ColumnCount { get; } = NCols.Num;\n    public static int RowCount { get; } = NRows.Num;\n\n    internal readonly float[,] values = new float[ColumnCount, RowCount];\n\n    public void Add(Tensor\u003cNCols, NRows\u003e tensor)\n    {\n        for (int col = 0; col \u003c ColumnCount; col++)\n            for (int row = 0; row \u003c RowCount; row++)\n                this.values[col, row] += tensor.values[col, row];\n    }\n}\n```\n\n## Shorthands\nFor non-power-of-two numerals it is useful to add shorthands.\nUnfortunately declaring one is rather verbose in C#:\n```csharp\nusing N39 = TypeNum.Sum\u003cTypeNum.Sum\u003cTypeNum.Sum\u003c\n\t\t\tTypeNum.N32,\n\t\t\tTypeNum.N4\u003e,\n\t\t\tTypeNum.N2\u003e,\n\t\t\tTypeNum.N1\u003e;\n\n...\n\nDebug.Assert(N39.Num == 39);\nvar thirtyNine = new Tensor\u003cN39, N39\u003e();\n```\n\n# Consistency\nTechnically, `Sum\u003cN1, N0\u003e` and `Sum\u003cN0, N1\u003e` represent the same numeral.\nHowever, there is no way to express it in C# type system. To alleviate that\nTypeNum tries to enforce one and only way to represent specific number.\n\nTo take advantage of that enforcement, avoid declaring your own implementations\nof the `Numeral` interface, and stick to `N*`, `Twice\u003cT\u003e`, and `Sum\u003cT1, T2\u003e`\nclasses. They enforce several rules at run time (and, potentially, [compile\ntime in the future](https://github.com/losttech/TypeNum/issues/1)):\n\n## Twice\nIn `Twice\u003cT\u003e` `T` can only be one of the following:\n\n* the largest predefined type numeral (currently `N4096`)\n* another `Twice\u003c*\u003e`\n\nSo `Twice\u003cT\u003e` can only be used to represent very large numerals\n\n## Sum\nThe following rules are enforced on parameters `T1` and `T2` of `Sum\u003cT1, T2\u003e`:\n\n* `T1.Num` must be strictly greater (\u003e) than `T2.Num` (swap them, if yours are opposite)\n* `T2` can never be another `Sum\u003c*,*\u003e`. Replace any `Sum\u003cA, Sum\u003cB, C\u003e\u003e` with\n`Sum\u003cSum\u003cA, B\u003e, C\u003e`\n* if `T1` itself is a `Sum\u003cA, B\u003e`, then in `Sum\u003cSum\u003cA, B\u003e, C\u003e` `A` and `B` must\neach be strictly greater (\u003e) than `C`\n\nFollowing these rules will ensure, that equal type numerals are always\nrepresented by identical types.\n\n# F# Example\nIn F# (unlike C#) operators can introduce new generic type parameters,\nwhich enables defining statically-typed matrix multiplication as an operator:\n\n```fsharp\ntype Matrix\u003c'rows, 'cols\u003e() =\n    static member ( * )(left: Matrix\u003c'rows, 'cols\u003e, right: Matrix\u003c'cols, 'ncols\u003e) =\n        Matrix\u003c'rows, 'ncols\u003e()\n\nmodule private Test =\n    open TypeNum\n\n    type N3 = Sum\u003cN2, N1\u003e\n    type N7 = Sum\u003cN4, N3\u003e\n    type N5 = Sum\u003cN4, N1\u003e\n\n    let a = Matrix\u003cN7, N5\u003e()\n    let b = Matrix\u003cN5, N3\u003e()\n    let product = a * b\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosttech%2Ftypenum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flosttech%2Ftypenum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosttech%2Ftypenum/lists"}