Macro polytype::tp[][src]

macro_rules! tp {
    ($n:ident) => { ... };
    ($n:ident($($x:expr),*)) => { ... };
    ($n:ident($($x:expr,)*)) => { ... };
    ($n:expr) => { ... };
    (@arrow[$x:expr]) => { ... };
    (@arrow[$x:expr, $($xs:expr),*]) => { ... };
    (@arrow[$x:expr, $($xs:expr,)*]) => { ... };
}

Creates a Type (convenience for common patterns).

Specifically, a Type<&'static str>, where all names are static strings.

This example is not tested
// Equivalent to:
Type::Constructed(ident, vec![
    tp1,
    tp2,
    ...
])
// or
Type::Variable(n)
// or
Type::arrow(
    tp0,
    Type::arrow(
        tp1,
        Type::arrow(
            tp2,
            ...,
        )
    )
)

Examples

Make a primitive type:

let t = tp!(int);
assert_eq!(format!("{}", t), "int");
// Equivalent to:
let t_eq = Type::Constructed("int", vec![]);
assert_eq!(t, t_eq);

Make a variable type:

let t = tp!(0);
assert_eq!(format!("{}", t), "t0");
// Equivalent to:
let t_eq = Type::Variable(0);
assert_eq!(t, t_eq);

Make a composite type:

let tint = tp!(int);
let tstr = tp!(str);
let t = tp!(dict(tstr, tint));
assert_eq!(format!("{}", t), "dict(str,int)");
// Equivalent to:
let t_eq = Type::Constructed("dict", vec![
    Type::Constructed("str", vec![]),
    Type::Constructed("int", vec![]),
]);
assert_eq!(t, t_eq);

Make an arrow:

let t = tp!(@arrow[Type::Variable(0), Type::Variable(1), Type::Variable(2)]);
assert_eq!(format!("{}", t), "t0 → t1 → t2");
// Equivalent to:
let t_eq = Type::arrow(
    Type::Variable(0),
    Type::arrow(
        Type::Variable(1),
        Type::Variable(2),
    )
);
assert_eq!(t, t_eq);

Nest them for more complex types:

// mapi: (int → α → β) → [α] → [β]
let t = tp!(@arrow[
    tp!(@arrow[tp!(int), tp!(0), tp!(1)]),
    tp!(list(tp!(0))),
    tp!(list(tp!(1))),
]);
assert_eq!(format!("{}", t), "(int → t0 → t1) → list(t0) → list(t1)");