algebraicdatas

This module provides the feature of algebraic data type and its associated method

Pure Nim score 15/100 · tests present · no docs generated

Summary

Latest Version 0.1.0
License MIT
CI Status Failing
Downloads 0
Last Indexed 2026-09-02 07:20

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

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