{"id":18453301,"url":"https://github.com/quasarbright/unitchecker","last_synced_at":"2025-06-23T09:04:41.441Z","repository":{"id":92838992,"uuid":"280535699","full_name":"quasarbright/UnitChecker","owner":"quasarbright","description":"A unit/type checker for physics equations","archived":false,"fork":false,"pushed_at":"2020-10-13T01:03:57.000Z","size":133,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-23T09:02:46.806Z","etag":null,"topics":["haskell","haskell-application","physics","physics-formulas","repl"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quasarbright.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","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":"2020-07-17T22:19:37.000Z","updated_at":"2020-10-13T01:03:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"56359815-399a-4cad-b34c-f07c0b794b8f","html_url":"https://github.com/quasarbright/UnitChecker","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/quasarbright/UnitChecker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2FUnitChecker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2FUnitChecker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2FUnitChecker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2FUnitChecker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quasarbright","download_url":"https://codeload.github.com/quasarbright/UnitChecker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2FUnitChecker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261449723,"owners_count":23159800,"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":["haskell","haskell-application","physics","physics-formulas","repl"],"created_at":"2024-11-06T07:35:48.761Z","updated_at":"2025-06-23T09:04:36.353Z","avatar_url":"https://github.com/quasarbright.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UnitChecker\n\nA tool for checking whether physics equations and expressions break the rules of units. i.e. you can't add meters and kilograms or raise e to the power of 2 meters\n\nFor an example displaying the syntax and all the features, see `examples/fma.unit`\n\n## Features\n* supports basic arithmetic expressions and (monomorphic) functions\n* checks that an expression is valid in terms of units\n* checks whether two expressions have the same units in an equation\n* define your own derived units\n* declare a variable's units and use it in expressions\n* define a variable to infer its units, then use it in expressions\n* define function signatures\n* common derived units (i.e. `N = [kg m s^-2]`), variables (i.e. `g :: [m s^-2]`), and functions (i.e. `sin :: ([]) -\u003e []`) are included in prelude\n* has a REPL\n\n## Examples\nMore detailed examples can be found in the `examples` directory. `examples/fma.unit` is a particularly good example of all features and syntax\n\nHere is an example of a program:\n\n```\nvar m :: [kg]\nvar v :: [m s^-1]\ndef p = m*v\neq (1/2) * m * v^2 = p^2 / (2*m)\ndef KE = (1/2) * m * v^2\n```\nThis program succeeds and outputs the following:\n```\nKE :: [kg m^2 s^-2]\nm :: [kg]\np :: [kg m s^-1]\nv :: [m s^-1]\n```\n\nWhen a program runs, it either outputs an error or outputs all variables with their units and all derived units with their definitions.\n\nRunning this\n```\nvar m :: [kg]\n\nvar a :: [m s^ -2]\n\ndef F = m * a \n\n// should give a mismatch error\nexpr F + m\n```\noutputs the error\n```\nUnit mismatch: Expected units of [kg m s^-2], but got units of [kg] at examples/mismatch.unit:8:6-8:11\n```\n\n## Syntax\na UnitChecker program consists of a list of statements.\nA statement can declare the units of a variable, define a variable and infer its units,\ndefine a derived unit (like Newtons), define the signature of a function, check the units of an expression,\nand check the units of both sides of an equation and check that they're equivalent\n\nAn expression is an arithmetic expression of variables and numbers with operators `+-*/^`, function calls, and unit annotations\n\nA unit is written like so: `[kg m^2 s^-2]`\n\nHere is the context free grammar for a program:\n```bnf\n\u003cprogram\u003e = \u003cstatement\u003e*\n\n\u003cstatement\u003e = 'def' \u003cidentifier\u003e '=' \u003cexpression\u003e\n            | 'var' \u003cidentifier\u003e '::' \u003cunit\u003e\n            | 'fun' \u003cidentifier\u003e '::' '(' \u003cunits\u003e? ')' '-\u003e' \u003cunit\u003e\n            | 'derived' \u003cidentifier\u003e '=' \u003cunit\u003e\n            | 'expr' \u003cexpr\u003e\n            | 'eq' \u003cexpr\u003e '=' \u003cexpr\u003e\n\n\u003cunits\u003e = \u003cunit\u003e | \u003cunit\u003e ',' \u003cunits\u003e \n\n\u003cexpr\u003e = \u003cexpr\u003e \u003cbinop\u003e \u003cexpr\u003e\n       | '-' \u003cexpr\u003e\n       | '(' \u003cexpr\u003e ')'\n       | \u003cidentifier\u003e '(' \u003cargs\u003e? ')'\n       | \u003cexpr\u003e '::' \u003cunit\u003e\n       | \u003cnumber\u003e\n       | \u003cidentifier\u003e\n\n\u003cargs\u003e = \u003cexpr\u003e | \u003cexpr\u003e ',' \u003cargs\u003e\n\n\u003cbinop\u003e = [-+*/^]\n\n\u003cunit\u003e = '[' \u003cbasePow\u003e* ']'\n\n\u003cbasePow\u003e = \u003cidentifier\u003e ('^' \u003cinteger\u003e)?\n```\n\n## Running\nYou can run a file like this:\n```\nunitChecker path/to/file.unit\n```\nif you are running from source, use `stack run` or `stack exec UnitChecker-exe`:\n```\nstack run path/to/file.unit\n```\nTo run the REPL, just run without specifying a file\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquasarbright%2Funitchecker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquasarbright%2Funitchecker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquasarbright%2Funitchecker/lists"}