Enum polytype::Type[][src]

pub enum Type<N: Name = &'static str> {
    Constructed(N, Vec<Type<N>>),
    Variable(Variable),
}
Expand description

Represents monotypes (fully instantiated, unquantified types).

The primary ways to create a Type are with either the tp! macro or TypeSchema::instantiate. Type::arrow constructs function types (i.e. α → β), as does conversion (Type::from) with Vec and VecDeque for curried arrows.

Variants

Constructed(N, Vec<Type<N>>)

Primitive or composite types (e.g. int, List(α), α → β)

Examples

Primitives have no associated types:

let tint = Type::Constructed("int", vec![]);
assert_eq!(tint.to_string(), "int")

Composites have associated types:

let tint = Type::Constructed("int", vec![]);
let tlist_of_ints = Type::Constructed("list", vec![tint]);
assert_eq!(tlist_of_ints.to_string(), "list(int)");

With the macro:

let t = tp!(list(tp!(int)));
assert_eq!(t.to_string(), "list(int)");

Function types, or “arrows”, are constructed with either Type::arrow, two implementations of Type::from — one for Vec<Type> and one for VecDeque<Type> — or the macro:

let t = Type::arrow(tp!(int), tp!(bool));
assert_eq!(t.to_string(), "int → bool");

let t = Type::from(vec![tp!(int), tp!(int), tp!(bool)]);
assert_eq!(t.to_string(), "int → int → bool");

let t = tp!(@arrow[tp!(int), tp!(int), tp!(bool)]); // prefer this over Type::from
assert_eq!(t.to_string(), "int → int → bool");

Tuple Fields of Constructed

0: N1: Vec<Type<N>>
Variable(Variable)

Type variables (e.g. α, β).

Examples

// any function: α → β
let t = tp!(@arrow[Type::Variable(0), Type::Variable(1)]);
assert_eq!(t.to_string(), "t0 → t1");

With the macro:

// map: (α → β) → [α] → [β]
let t = tp!(@arrow[
    tp!(@arrow[tp!(0), tp!(1)]),
    tp!(list(tp!(0))),
    tp!(list(tp!(1))),
]);
assert_eq!(t.to_string(), "(t0 → t1) → list(t0) → list(t1)");

Tuple Fields of Variable

0: Variable

Implementations

Parse a type from a string. This round-trips with Display. This is a leaky operation and should be avoided wherever possible: names of constructed types will remain until program termination.

Examples

let t_par = Type::parse("int -> hashmap(str, list(bool))").expect("valid type");
let t_lit = tp!(@arrow[
    tp!(int),
    tp!(hashmap(
        tp!(str),
        tp!(list(tp!(bool))),
    )),
]);
assert_eq!(t_par, t_lit);

let s = "(t1 → t0 → t1) → t1 → list(t0) → t1";
let t: Type<&'static str> = Type::parse(s).expect("valid type");
let round_trip = t.to_string();
assert_eq!(s, round_trip);

Construct a function type (i.e. alphabeta).

Examples

let t = Type::arrow(tp!(int), tp!(bool));
assert_eq!(t.to_string(), "int → bool");

If the type is an arrow, get its associated argument and return types.

Examples

let t = tp!(@arrow[tp!(int), tp!(int), tp!(bool)]);
if let Some((left, right)) = t.as_arrow() {
    assert_eq!(left.to_string(), "int");
    assert_eq!(right.to_string(), "int → bool");
} else { unreachable!() }

If the type is an arrow, recursively get all curried function arguments.

Examples

let t = tp!(@arrow[tp!(int), tp!(int), tp!(bool)]);
if let Some(args) = t.args() {
    assert_eq!(args.len(), 2);
    assert_eq!(args[0].to_string(), "int");
    assert_eq!(args[1].to_string(), "int");
} else { unreachable!() }

If the type is an arrow, recursively get all curried function arguments.

If the type is an arrow, get its ultimate return type.

Examples

let t = tp!(@arrow[tp!(int), tp!(int), tp!(bool)]);
if let Some(ret) = t.returns() {
    assert_eq!(ret.to_string(), "bool");
} else { unreachable!() }

Applies the type in a Context.

This will substitute type variables for the values associated with them by the context.

Examples

let mut ctx = Context::default();
ctx.unify(&tp!(0), &tp!(int)).expect("unifies");

let t = tp!(list(tp!(0)));
assert_eq!(t.to_string(), "list(t0)");
let t = t.apply(&ctx);
assert_eq!(t.to_string(), "list(int)");

Like apply_compress, but works in-place.

Generalizes the type by quantifying over free variables in a TypeSchema.

Variables specified by bound remain unquantified.

Examples

let t = tp!(@arrow[tp!(0), tp!(1)]);
assert_eq!(t.to_string(), "t0 → t1");

let mut ctx = Context::default();
ctx.extend(0, tp!(int));

let t_gen = t.apply(&ctx).generalize(&[]);
assert_eq!(t_gen.to_string(), "∀t1. int → t1");

let t_gen = t.apply(&ctx).generalize(&[1]);
assert_eq!(t_gen.to_string(), "int → t1");

Compute all the variables present in a type.

Examples

let t = tp!(@arrow[tp!(0), tp!(1)]);
assert_eq!(t.to_string(), "t0 → t1");

let mut vars = t.vars();
vars.sort();
assert_eq!(vars, vec![0, 1]);

Perform a substitution. This is analogous to apply.

Examples

let t = tp!(@arrow[tp!(0), tp!(1)]);
assert_eq!(t.to_string(), "t0 → t1");

let mut substitution = HashMap::new();
substitution.insert(0, tp!(int));
substitution.insert(1, tp!(bool));

let t = t.substitute(&substitution);
assert_eq!(t.to_string(), "int → bool");

Like substitute, but works in-place.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Formats the value using the given formatter. Read more

Performs the conversion.

Performs the conversion.

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Compare self to key and return true if they are equal.

Performs the conversion.

Performs the conversion.

The resulting type after obtaining ownership.

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

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

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

Converts the given value to a String. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.