#list #const-generics #static #heap-allocation

无std slist

具有静态确定大小的栈上生存的代数列表

3个版本

0.1.2 2020年9月7日
0.1.1 2020年8月13日
0.1.0 2020年8月13日

#570 in 数学

每月23次下载

MIT许可

42KB
909 代码行

s(tatic|tack)list

Build status Crates.io status Docs

具有静态确定大小且在栈上生存的实验性代数列表。它们可以迭代、映射、折叠、过滤,并且具有连续存储。#![no_std],无const泛型,无宏,无不安全代码,无堆分配或装箱,无动态调度,无依赖项,无用于实现的非稳定代码。只有Rust特质系统。

列表的构建方式类似于皮亚诺算术中的自然数。例如,具有8个元素的列表类型是

let l: List<T, List<T, List<T, List<T, List<T, List<T, List<T, List<T, ()>>>>>>>>;

当列表被过滤时,结果可以是任意子列表,因此返回的类型是小于原始列表的所有列表的并集

let s: Either<List<T, List<T, List<T, List<T, List<T, List<T, List<T, List<T, ()>>>>>>>>, Either<List<T, List<T, List<T, List<T, List<T, List<T, List<T, ()>>>>>>>, Either<List<T, List<T, List<T, List<T, List<T, List<T, ()>>>>>>, Either<List<T, List<T, List<T, List<T, List<T, ()>>>>>, Either<List<T, List<T, List<T, List<T, ()>>>>, Either<List<T, List<T, List<T, ()>>>, Either<List<T, List<T, ()>>, Either<List<T, ()>, Either<(), Void>>>>>>>>>;

虽然编写起来非常麻烦,但在实际实现中,它具有线性内存效率,并且比原始列表只多一个标签,这是尽可能短的,因为长度仅在运行时确定。这样,可以在具有可变但有限长度的列表上执行计算。

slist宏可用于快速创建列表(实际实现中不包含宏)

use slist::prelude::*;

let list = slist![0_usize, 3, 10, 19, 12, 22, 28, 13, 6].map(|i| i + 1);
let filtered = list.filter(|u| (u % 2) == 0);
assert_eq!(filtered + slist![3, 4, 5], slist![4, 20, 14, 3, 4, 5]);
assert_eq!(slist![6, 7] * slist![false, true], slist![(6, false), (7, false), (6, true), (7, true)]);

let mut list = slist![4, 5, 6];
for i in list.as_mut() {
    *i += 2;
}
assert_eq!(list, slist![6, 7, 8]);

请注意,当提供表达式和大小后,slist宏将为每个元素分别评估表达式。这与数组构造函数(或vec宏)不同,可用于迭代构建有限列表,例如从标准输入中的数字

use slist::prelude::*;

let stdin = std::io::stdin();
let mut inputs = stdin.lock().lines().filter_map(Result::ok).map(|s| s.parse::<u16>().ok());

let list = slist![inputs.next().flatten(); 4];
let list = list.filter_map(|i| i);

宏仅用于方便,并非库功能所必需。例如,前面的代码被展开为

let list = {
    use slist::List;
    let list: List<(), List<(), List<(), List<(), List<(), ()>>>>> = Default::default();
    list.map(|_| inputs.next().flatten())
};

如果您喜欢以皮亚诺形式编写自然数,则根本不需要任何宏。

遗憾的是,在泛型关联类型稳定之前,列表映射、从列表的引用创建引用列表的功能需要由单独的特质提供,分别是SlistMap<T, U>,以及SlistAsRef<'a, T>。本crate提供了一个prelude模块,可以方便地导入此类特质。

本crate可能会对编译器造成较大负担,在生产环境中使用可能会有风险。

许可证:MIT

依赖项