import std.variant : Algebraic, This, visit;
import std.typecons : Tuple, tuple;
alias List(T) = Algebraic!(Nil, Tuple!(T, "head", This*, "tail"));
alias Cons(T) = Tuple!(T, "head", List!T*, "tail");
List!T* list(T)(T[] items...)
return new List!T(Nil());
return new List!T(Cons!T(items[0], list(items[1 .. $])));
string list2string(T)(List!T list)
import std.stdio : write;
list.visit!((Nil _) => "nil",
(Cons!T cons) => "cons(" ~ cons.head ~ ", " ~ list2string(*cons.tail) ~ ")");
List!int* myList = list(1, 2, 3);
assert(list2string(*myList) == "cons(1, cons(2, cons(3, nil)))");