#functor #operator #typed #traits #aliases #t-list

nightly type-freak

类型化数据结构、特质运算符和别名集合

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阶段,我很乐意接受贡献!

用法

将此行添加到您的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