Tuples.bruijn


# MIT License, Copyright (c) 2025 Marvin Borner

:import std/Combinator .

tuple [[[0 2 1]]] ⧗ a → b → (Tuple a b)

…:… tuple

triple [[[[0 3 2 1]]]] ⧗ a → b → c → (Triple a b c)

…:…:… triple

quadruple [[[[[0 4 3 2 1]]]]] ⧗ a → b → c → d → (Quadruple a b c d)

…:…:…:… quadruple

quintuple [[[[[[0 5 4 3 2 1]]]]]] ⧗ a → b → c → d → e → (Quintuple a b c d e)

…:…:…:…:… quintuple

sextuple [[[[[[[0 6 5 4 3 2 1]]]]]]] ⧗ a → b → c → d → e → f → (Sextuple a b c d e f)

…:…:…:…:…:… sextuple

septuple [[[[[[[[0 7 6 5 4 3 2 1]]]]]]]] ⧗ a → b → c → d → e → f → g → (Septuple a b c d e f g)

…:…:…:…:…:…:… septuple

octuple [[[[[[[[[0 8 7 6 5 4 3 2 1]]]]]]]]] ⧗ a → b → c → d → e → f → g → h → (Octuple a b c d e f g h)

…:…:…:…:…:…:…:… octuple

nonuple [[[[[[[[[[0 9 8 7 6 5 4 3 2 1]]]]]]]]]] ⧗ a → b → c → d → e → f → g → h → i → (Nonuple a b c d e f g h i)

…:…:…:…:…:…:…:…:… nonuple

# allocates a tuple of size n with a default element
alloc [[1 (t 0)]] ⧗ Unary → (a → (NTuple a))

:test (alloc (+3u) [[1]]) ([[1]] : [[1]] : [[1]])

# adds an element to the front of a tuple
push [[[1 (0 2)]]] ⧗ a → (NTuple a) → (NTuple a)

:test (push (+0d) ((+1d) : (+2d))) ((+0d) : (+1d) : (+2d))

# removes the head of a tuple
pop [[1 [1]]] ⧗ (NTuple a) → (NTuple a)

:test (pop ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+2u) : (+3u) : (+4u))

# removes the nth element of a tuple
pop-n [[[1 (2 b k 0)]]] ⧗ Unary → (NTuple a) → (NTuple a)

:test (pop-n (+0u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+2u) : (+3u) : (+4u))
:test (pop-n (+1u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+0u) : (+2u) : (+3u) : (+4u))
:test (pop-n (+2u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+0u) : (+1u) : (+3u) : (+4u))
:test (pop-n (+3u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+0u) : (+1u) : (+2u) : (+4u))
:test (pop-n (+4u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+0u) : (+1u) : (+2u) : (+3u))

# moves the head to the nth position
move [[[1 [3 b [0 1] 1]]]] ⧗ Unary → (NTuple a) → (NTuple a)

:test (move (+0u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))
:test (move (+1u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+0u) : (+2u) : (+3u) : (+4u))
:test (move (+2u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+2u) : (+0u) : (+3u) : (+4u))
:test (move (+3u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+2u) : (+3u) : (+0u) : (+4u))
:test (move (+4u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+2u) : (+3u) : (+4u) : (+0u))

# shifts the head to the end, requires size of tuple
shift move ⧗ Unary → (NTuple a) → (NTuple a)

:test (shift (+4u) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+1u) : (+2u) : (+3u) : (+4u) : (+0u))
:test ((+5u) (shift (+4u)) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))) ((+0u) : (+1u) : (+2u) : (+3u) : (+4u))

# constructs selector for kth element of n-tuple
select [[0 (t i) ((1 k) (0 k))]] ⧗ Unary → Unary → ((NTuple a) → a)

:test (select (+5u) (+0u)) ([[[[[[0]]]]]])
:test (select (+5u) (+3u)) ([[[[[[3]]]]]])