4个版本
0.2.0 | 2019年9月29日 |
---|---|
0.1.2 | 2019年9月25日 |
0.1.1 | 2019年9月25日 |
0.1.0 | 2019年9月25日 |
#845 在 数据结构
110KB
2.5K SLoC
类型狂热者
该包是一组类型化数据结构、特质运算符和有用的类型别名,旨在支持tch-typed-tensor项目,该项目提供了编译时检查的张量类型。
通过设计减少运行时计算量。DSTs通过特质运算符操作。也就是说,利用Rust的关联类型和泛型,我们可以构建如列表和键值映射等非平凡类型。
到目前为止,该包提供了以下功能。它仍处于alpha阶段,我很乐意接受贡献!
- TList:一个键为任意类型的类型化列表。
- KVList:类似于TList,但额外包含值。
- Boolean:类型化布尔代数。
- Maybe:与
std::option::Option
类似的特质。 - Counter:构建递归特质运算符的方便类型。
- 功能性原语:提供
Functor
、Compose
和Applicative
等。 - 元组类型的特质运算符
- 控制流:类型化的
If
、IfLess
、IfSame
等,用于编译时守卫和静态断言。
用法
将此行添加到您的Cargo.toml
文件中。请注意,该包仍处于alpha阶段。稳定的API无法保证。
type-freak = "~0"
示例
编译时守卫和静态断言
要断言一个类型化整数小于另一个类型化整数
use typenum::consts::*;
use type_freak::control::IfLessOutput;
type Out1 = IfLessOutput<usize, U3, U5>; // U3 < U5 is true, thus Out1 ~= usize
type Out2 = IfLessOutput<usize, U5, U3>; // U5 < U5 is false
fn assert() {
let _: Out1 = 0; // Goes fine here.
let _: Out2 = 0; // Compile error!!!
}
我们可以通过IfSame
特质边界确保两个泛型参数是同一类型。
use type_freak::control::IfSame;
fn guarded_function<Lhs, Rhs>() -> String
where
Lhs: IfSame<Lhs, Rhs>
{
"Yeeeeeee!".to_owned()
}
fn comile_me() {
let _ = guarded_function::<String, String>(); // fine
let _ = guarded_function::<String, u8>(); // Compile error!!!
}
类型化列表
《TList》类型表示任意类型的列表。它可以通过《TListType!`》宏来构造。该库提供了一系列作为《类型操作符》的特质来操作列表结构。
use type_freak::{TListType, list::*};
type List1 = TListType![u8, u16, u32];
type List2 = LPrepend<List1, u64>;
// List2 ~= TListType![u64, u8, u16, u32]
type List3<Index1> = LRemoveAt<List2, u16, Index1>;
// List3<_> ~= TListType![u64, u8, u32]
type List4<Index1> = LAppend<List3<Index1>, f32>;
// List4 ~= TListType![u64, u8, u32, f32]
type List5<Index1, Index2> = LInsertAt<List4<Index1>, u8, f64, Index2>;
// List5 ~= TListType![u64, u8, f64, u32, f32]
功能接口
您可以使用库中现有的泛型函数映射、过滤或扫描《TList》。也可以自定义泛型函数以轻松操作数据。
struct BoxFunctor;
impl<Input> Functor<Input> for BoxFunctor {
type Output = Box<Input>;
}
type ListBefore = TListType![String, [i64; 7], isize, (), (f64, f32)];
type ListAfter = LMap<List3, BoxFunctor>;
type Assert = IfSameOutput<
(),
ListAfter,
TListType! {
Box<String>,
Box<[i64; 7]>,
Box<isize>,
Box<()>,
Box<(f64, f32)>
},
>;
fn assert() {
let _: Assert = (); // static assertion
}
特质级别的《Option`
《Maybe`与std的《Option`类似。
use typenum::consts::*;
use type_freak::maybe::{Maybe, Just, Nothing};
type Opt1 = Just<U3>;
type Opt2 = Nothing;
type Val1 = Unwrap<Opt1>; // U3
type Val2 = UnwrapOr<Opt1, U0>; // U3
type Val3 = UnwrapOr<Opt2, U0>; // U0
自动推断计数器
《Counter`特质以及《Next`和《Current`类型是构建递归类型操作符的有用工具。以下示例实现了一个从《TList`中删除特定类型的特质。
该示例通过终止步骤和递归步骤工作,对应于impl块。请注意,《Index`参数是必要的,以便编译器区分两个impl块的签名。否则,编译器将抱怨存在冲突的实现。
use type_freak::{
list::{TList, LCons, LNil},
counter::{Counter, Current, Next},
};
/* Definition */
pub trait LRemoveAt<Target, Index>
where
Index: Counter,
Self: TList,
Self::Output: TList,
{
type Output;
}
// termination step
impl<Target, Tail> LRemoveAt<Target, Current> for LCons<Target, Tail>
where
Tail: TList,
{
type Output = Tail;
}
// recursion step
impl<Target, Index, NonTarget, Tail> LRemoveAt<Target, Next<Index>> for LCons<NonTarget, Tail>
where
Index: Counter,
Tail: TList + LRemoveAt<Target, Index>,
{
type Output = LCons<NonTarget, <Tail as LRemoveAt<Target, Index>>::Output>;
}
/* Auto-inference example */
// Here SomeList is equivalent to TListType![u8, u32]
type SomeList<Index> = <TListType![u8, u16, u32] as LRemoveAt<u16, Index>>::Output;
// The Index argument can be inferred by compiler
fn auto_inference() {
let _ = SomeList::<_>::new();
}
许可证
本项目采用《MIT》或《Apache 2.0》许可证。选择适合您的许可证。
依赖关系
~155KB