Struct arithmetic_typing::Tuple

source ·
pub struct Tuple<Prim: PrimitiveType = Num> { /* private fields */ }
Expand description

Tuple type.

Most generally, a tuple type consists of three fragments: start, middle and end. Types at the start and at the end are heterogeneous, while the middle always contains items of the same type (but the number of these items can generally vary). A Slice is a partial case of a tuple type; i.e., a type with the empty start and end. Likewise, a Rust-like tuple is a tuple that only has a start.

§Notation

A tuple type is denoted like (T, U, ...[V; _], X, Y), where T and U are types at the start, V is the middle type, and X, Y are types at the end. The number of middle elements can be parametric, such as N. If a tuple only has a start, this notation collapses into Rust-like (T, U). If a tuple only has a middle part (Self::as_slice() returns Some(_)), it is denoted as the corresponding slice, something like [T; N].

§Indexing

Indexing is accessing tuple elements via an expression like xs.0. Tuple indexing is supported via FieldAccess expr, where the field name is a decimal usize number.

The indexing support for type inference is quite limited. For it to work, the receiver type must be known to be a tuple, and the index must be such that the type of the corresponding element is decidable. Otherwise, an UnsupportedIndex error will be raised.

Tuple typeIndexOutcome
(Num, Bool)0Num
(Num, Bool)1Bool
(Num, Bool)2Hard error; the index is out of bounds.
Num0Hard error; only tuples can be indexed.
[Num; _]0Error; the slice may be empty.
[Num; _ + 1]0Num; the slice is guaranteed to have 0th element.
(Bool, ...[Num; _])0Bool
(Bool, ...[Num; _])1Error; the slice part may be empty.
(...[Num; _], Bool)0Error; cannot decide if the result is Num or Bool.

§Examples

Simple tuples can be created using the From trait. Complex tuples can be created via Self::new().

let simple_tuple = Tuple::from(vec![Type::NUM, Type::BOOL]);
assert_matches!(simple_tuple.parts(), ([_, _], None, []));
assert!(simple_tuple.as_slice().is_none());
assert_eq!(simple_tuple.to_string(), "(Num, Bool)");

let slice_tuple = Tuple::from(
   Type::NUM.repeat(UnknownLen::param(0)),
);
assert_matches!(slice_tuple.parts(), ([], Some(_), []));
assert!(slice_tuple.as_slice().is_some());
assert_eq!(slice_tuple.to_string(), "[Num; N]");

let complex_tuple = Tuple::new(
    vec![Type::NUM],
    Type::NUM.repeat(UnknownLen::param(0)),
    vec![Type::BOOL, Type::param(0)],
);
assert_matches!(complex_tuple.parts(), ([_], Some(_), [_, _]));
assert_eq!(complex_tuple.to_string(), "(Num, ...[Num; N], Bool, 'T)");

Implementations§

source§

impl<Prim: PrimitiveType> Tuple<Prim>

source

pub fn new( start: Vec<Type<Prim>>, middle: Slice<Prim>, end: Vec<Type<Prim>>, ) -> Self

Creates a new complex tuple.

source

pub fn as_slice(&self) -> Option<&Slice<Prim>>

Returns this tuple as slice if it fits (has no start or end components).

source

pub fn parts(&self) -> (&[Type<Prim>], Option<&Slice<Prim>>, &[Type<Prim>])

Returns shared references to the parts comprising this tuple: start, middle, and end.

source

pub fn parts_mut( &mut self, ) -> (&mut [Type<Prim>], Option<&mut Slice<Prim>>, &mut [Type<Prim>])

Returns exclusive references to the parts comprising this tuple: start, middle, and end.

source

pub fn len(&self) -> TupleLen

Returns the length of this tuple.

§Examples
let tuple = Tuple::from(vec![Type::NUM, Type::BOOL]);
assert_eq!(tuple.len(), TupleLen::from(2));

let slice = Slice::new(Type::NUM, UnknownLen::param(0));
let tuple = Tuple::from(slice.clone());
assert_eq!(tuple.len(), TupleLen::from(UnknownLen::param(0)));

let tuple = Tuple::new(vec![], slice, vec![Type::BOOL]);
assert_eq!(tuple.len(), UnknownLen::param(0) + 1);
source

pub fn is_empty(&self) -> bool

Returns true iff this tuple is guaranteed to be empty.

source

pub fn element_types( &self, ) -> impl Iterator<Item = (TupleIndex, &Type<Prim>)> + '_

Iterates over all distinct elements in this tuple. The iteration is performed in order.

§Examples
let complex_tuple = Tuple::new(
    vec![Type::NUM],
    Slice::new(Type::NUM, UnknownLen::param(0)),
    vec![Type::BOOL, Type::param(0)],
);
let elements: Vec<_> = complex_tuple.element_types().collect();
assert_eq!(elements, [
    (TupleIndex::Start(0), &Type::NUM),
    (TupleIndex::Middle, &Type::NUM),
    (TupleIndex::End(0), &Type::BOOL),
    (TupleIndex::End(1), &Type::param(0)),
]);

Trait Implementations§

source§

impl<Prim: Clone + PrimitiveType> Clone for Tuple<Prim>

source§

fn clone(&self) -> Tuple<Prim>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<Prim: Debug + PrimitiveType> Debug for Tuple<Prim>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<Prim: PrimitiveType> Display for Tuple<Prim>

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<Prim: PrimitiveType> From<Slice<Prim>> for Tuple<Prim>

source§

fn from(slice: Slice<Prim>) -> Self

Converts to this type from the input type.
source§

impl<Prim: PrimitiveType> From<Tuple<Prim>> for Type<Prim>

source§

fn from(tuple: Tuple<Prim>) -> Self

Converts to this type from the input type.
source§

impl<Prim: PrimitiveType> From<Vec<Type<Prim>>> for Tuple<Prim>

source§

fn from(elements: Vec<Type<Prim>>) -> Self

Converts to this type from the input type.
source§

impl<Prim: PrimitiveType> PartialEq for Tuple<Prim>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<Prim> Freeze for Tuple<Prim>

§

impl<Prim = Num> !RefUnwindSafe for Tuple<Prim>

§

impl<Prim> Send for Tuple<Prim>

§

impl<Prim> Sync for Tuple<Prim>

§

impl<Prim> Unpin for Tuple<Prim>
where Prim: Unpin,

§

impl<Prim = Num> !UnwindSafe for Tuple<Prim>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.