Struct arithmetic_typing::DynConstraints

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

Arbitrary type implementing certain constraints. Similar to dyn _ types in Rust or use of interfaces in type position in TypeScript.

Constraints in this type must be object-safe. DynConstraints can also specify an Object constraint, which can be converted to it using the From trait.

§Notation

  • If the constraints do not include an object constraint, they are Displayed like a ConstraintSet with dyn prefix; e.g, dyn Lin + Hash.
  • If the constraints include an object constraint, it is specified before all other constraints, but after the dyn prefix; e.g., dyn { x: Num } + Lin.

§Examples

dyn _ types can be used to express that any types satisfying certain constraints should be accepted.

let code = "
    sum_lengths = |...pts: dyn { x: _, y: _ }| {
        pts.fold(0, |acc, { x, y }| acc + sqrt(x * x + y * y))
    };
    sum_lengths(#{ x: 1, y: 2 }, #{ x: 3, y: 4, z: 5 })
";
let ast = Annotated::<F32Grammar>::parse_statements(code)?;

let mut env = TypeEnvironment::new();
let sqrt = Function::builder().with_arg(Type::NUM).returning(Type::NUM);
env.insert("fold", Prelude::Fold).insert("sqrt", sqrt);
env.process_statements(&ast)?;

assert_eq!(
    env["sum_lengths"].to_string(),
    "(...[dyn { x: Num, y: Num }; N]) -> Num"
);

One of primary use cases of dyn _ is restricting varargs of a function:

// Function that accepts any amount of linear args (not necessarily
// of the same type) and returns a number.
let digest_fn = Type::try_from(&TypeAst::try_from("(...[dyn Lin; N]) -> Num")?)?;
let mut env = TypeEnvironment::new();
env.insert("true", Prelude::True).insert("digest", digest_fn);

let code = "
    digest(1, 2, (3, 4), #{ x: 5, y: (6,) }) == 1;
    digest(3, true) == 0; // fails: `true` is not linear
";
let ast = Annotated::<F32Grammar>::parse_statements(code)?;
let errors = env.process_statements(&ast).unwrap_err();

let err = errors.iter().next().unwrap();
assert_eq!(err.main_location().span(code), "true");
assert_matches!(err.kind(), ErrorKind::FailedConstraint { .. });

Implementations§

source§

impl<Prim: PrimitiveType> DynConstraints<Prim>

source

pub fn just(constraint: impl ObjectSafeConstraint<Prim>) -> Self

Creates constraints based on a single constraint.

source

pub fn is_empty(&self) -> bool

Checks if this constraint set is empty.

source

pub fn object(&self) -> Option<&Object<Prim>>

Returns the enclosed object constraint, if any.

source

pub fn insert(&mut self, constraint: impl ObjectSafeConstraint<Prim>)

Adds the specified constraint to these constraints.

Trait Implementations§

source§

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

source§

fn clone(&self) -> DynConstraints<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: PrimitiveType> Debug for DynConstraints<Prim>

source§

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

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

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

source§

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

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

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

source§

fn from(constraints: DynConstraints<Prim>) -> Self

Converts to this type from the input type.
source§

impl<Prim: PrimitiveType> From<Object<Prim>> for DynConstraints<Prim>

source§

fn from(object: Object<Prim>) -> Self

Converts to this type from the input type.
source§

impl<Prim: PartialEq + PrimitiveType> PartialEq for DynConstraints<Prim>

source§

fn eq(&self, other: &DynConstraints<Prim>) -> 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.
source§

impl<Prim: PrimitiveType> StructuralPartialEq for DynConstraints<Prim>

Auto Trait Implementations§

§

impl<Prim> Freeze for DynConstraints<Prim>

§

impl<Prim> !RefUnwindSafe for DynConstraints<Prim>

§

impl<Prim> Send for DynConstraints<Prim>

§

impl<Prim> Sync for DynConstraints<Prim>

§

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

§

impl<Prim> !UnwindSafe for DynConstraints<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.