algebraicdatas
This module provides the feature of algebraic data type and its associated method
Summary
| Latest Version | 0.1.0 |
|---|---|
| License | MIT |
| CI Status | Failing |
| Downloads | 0 |
| Last Indexed | 2026-09-02 07:20 |
Tags
Authors
- chocobo333
Installation
nimble install algebraicdatas
choosenim install algebraicdatas
git clone https://github.com/chocobo333/AlgebraicDataTypes
OS Compatibility
| Platform | Linux | macOS | Windows | FreeBSD | OpenBSD | NetBSD | Android | iOS | WASM | Embedded |
|---|---|---|---|---|---|---|---|---|---|---|
| algebraicdatas | ✓ | ✓ | ✓ | - | - | - | - | - | - | - |
Dependencies
| Package | Version | Optional |
|---|---|---|
| nim >= | 1.4.0 | No |
| ast_pattern_matching | - | No |
| macroutils | - | No |
| optionsutils | - | No |
Source
| Repository | https://github.com/chocobo333/AlgebraicDataTypes |
|---|---|
| Homepage | https://github.com/chocobo333/AlgebraicDataTypes |
| Registry Source | nimble_official |
README
AlgebraicDatas
This package literally provides algebraic data types(ADT) and performs pattern matching for them. It's inspried by some packages: ast-pattern-mathing and gara, and enum and pattern matching in the Rust language.
It provids two macros:
* `?=` macro
It can be used like Rust's if let syntax.
nim
let a = Option.Some(3)
if Some(val) ?= a:
echo val #> 3
if None ?= a:
echo "none"
* match macro
It's used for pattern matching. It's internally a compostion of if-else statement and `?=` macros.
nim
let a = Option.Some(3)
match a
of Some(val):
echo val #> 3
of None:
echo "none"
If you are using CaseStatementMacros, an experimental feature via {.experimental: "caseStmtMacros".}, you can use the case syntax instead of the match macro.
nim
let a = Option.Some(3)
case a # not `match`
of Some(val):
echo val #> 3
of None:
echo "none"
You can use case syntax and match macro as an expression.
nim
let
a = Option.Some(3)
b = case a # The same goes for `match` macro
of Some(val):
val
of _:
0
echo b #> 3
Features
ADT
TODO: write motivation to implement
Defining an ADT
You can define an ADT by using a macro called Algebraic. It looks like this:
Algebraic Option[T]:
Some(T)
None
Pattern mathing
Discarding
A discarding pattern _ will match anything. It will be used when you want to evaluate a branch ignoring the value.
let a = "a"
match a:
of _:
echo "hello"
#> hello
expands to:
if true:
echo "hello"
and,
let a = "a"
match a:
of anyPattern:
echo "hello"
of _:
echo "world"
roughly expands to:
if anyPattern ?= a:
echo "hello"
else:
echo "world"
Value
You can use value pattern with AtomType or string type as you does in case statement. Examples would be:
let a = 2
{.hint: "When you use case statement macro instead of `match` macro with string type, int type or ordered types, the Nim compiler dose not invoke `match` macro but the built-in case statement.".}
match a: # colon is needed on `match` macro
of 1:
echo "One"
of 2:
echo "Two"
of _:
echo "Any number"
#> Two
Range pattern
let a = 2
match a:
of 0:
echo "Zero"
of 1..int.high:
echo "Positive"
of int.low .. -1:
echo "Negative"
#> Positive
Named variable
let a = (3, 4)
case a # colon is optional on `case` statement macro
of (b, _):
echo b
#> 3
Existing variable
let
a = (3, 4)
b = 1
c = 3
case a
of (!b, _):
echo "a[0] == b"
of (!c, _):
echo "a[0] == c"
of _:
echo "not match"
#> a[0] == c
Tuple
Defining a tuple like below:
type Color = tuple
r: uint8
g: uint8
b: uint8
a: uint8
Destructing a tuple
var red: Color = (r: 255'u8, g: 1'u8, b: 2'u8, a: 3'u8)
case red
of (r: 255, g: _, b, a: _):
echo b
#> 2
Same value
var red: Color = (r: 128, g: 128, b: 255, a: 255)
case red
of (r, r, b, b):
echo "match"
#> match
case red
of (r, g: r, b: r@_, a: r):
echo r
#> 255
case red
of (r, b: r, g: r@_, a: r):
echo r
Tuple (who has unnamed field)
Defining a tuple like below:
type Color = (int8, int8, int8, int8)
var red: Color = (255, 0, 0, 255)
case red
of (a1, a2, a3, a4):
echo a1 + a2 + a3 + a4
#> 510
plan:
like field pattern
case red
of (0: a1, 1: a2, 2: a3, 3: a4):
echo a1 + a2 + a3 + a4
Object
The same goes for the tuple pattern
Nil pattern
not implemented yet
You can use Nil pattern nil with nillable object, namely ref object or ptr object.
var
fs = newFileStream("example.txt", fmRead)
line: string
case fs
of nil:
raise newException(IOError, "Not found such file")
of _:
while fs.readLine(line):
echo line
fs.close()
License
Mit License
author: chocobo333
Internal implementations
TODO: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
TODO
- [ ] documentation
- [ ] smarter error infomation: tuple length check, wheter ofBranch is, wheter discard pattern is, and so on
-
[ ] detect whether
==is declared and emit error -
[ ] support for slice(range) pattern
- [ ] string
- [ ] regular expression
- [ ] support for seq
- [ ] support for Table
- [ ] support for set
- [ ] support for NimNode
-
[ ] general variant object
-
[ ] check whether exhaustive or not
-
[ ] else branch
-
[ ] refactoring
-
[ ] strict func
- [ ] view types