#hlist #heterogeneous #safe

no-std hlist2

Compile-time heterogeneous list implementation

13 releases

0.0.15 Sep 2, 2024
0.0.14 Sep 8, 2023
0.0.13 Jun 24, 2023
0.0.8 May 3, 2023
0.0.2 Jan 17, 2023

#422 in Rust patterns

34 downloads per month

MIT/Apache

81KB
1.5K SLoC

hlist2

Crate Docs License

This crate defines a way to create compile-time heterogenous lists, or lists consisting of multiple types.

Heterogenous lists

This crate defines types for an empty list, Nil, and for pair of list head and its remainder, Cons. Heterogenous list consists of many conses contained recursively one in another, and the last cons with the last element contains nil as the remainder. For example, heterogenous list of integer, double and bool can be represented as Cons(1, Cons(2.0, Cons(true, Nil))) with type of Cons<i32, Cons<f64, Cons<bool, Nil>>>.

Recursive nature and behavior

Such recursive nature of heterogenous list allows us to implement various traits recursively and without any restrictions on the size of such list or types contained in it. Unlike tuples, traits can be implemented for all heterogenous lists and even for those which count of elements is bigger than 12, lack of which for tuples is a problem sometimes.

All heterogenous lists implement HList trait, so it can be used in generics. For example, this can be useful to bound generic type to be heterogenous list. To implement your trait for all heterogenous lists of any size, first implement it on Nil type, which is HList too. Then, implement your trait on Cons struct with head and tail generic types where tail type is heterogenous list too (or which implement HList trait).

Examples of these technique can be viewed in ops module, where all the specific operations for all heterogenous list types are implemented. For example, to append any value to the end of the list, use Append trait; to prepend any value to the beginning of the list, use Prepend trait, and so on.

Constructing and destructing heterogenous lists

But such recursive nature can be a problem when we try to name the type of heterogenous list or use pattern matching with values of heterogenous lists. To simplify creation of lists and naming of list types the crate defines two macros, hlist! and HList!. The first one should be used for creation of heterogenous lists or for pattern matching, while the second one should be used to name the type of heterogenous list.

So instead of writing Cons(1, Cons(2.0, Cons(true, Nil))) we can write more readable expression like hlist![1, 2.0, true].

To name the type of such list, we can write HList![i32, f64, bool] instead of Cons<i32, Cons<f64, Cons<bool, Nil>>>.

Tuple compatibility

Also this crate has a compatibility with tuple types. It implements conversion between heterogenous lists and their tuple forms when tuple has length of 12 and less, and vise versa.

Features

This crate uses no unsafe code to provide the same safety guarantees the Rust programming language provides.

This crate is no_std, so it can be used freely and with no fear in embedded environment.

Inspirations

This crate is intended to be an alternative to unmaintained hlist crate. This is also inspired by another open source crate frunk.

License

Licensed under either of

at your option.

No runtime deps