#### Dynamic Supertypes

For every subtype realtion. `P <: Q`, there is an implied conversion function of type `P -> Q`. This conversion does not need to be injective, nor does there need to be "retraction" function of type `Q -> Maybe P`.

But sometimes, this retraction does exist. Pinafore provides a general mechanism for making use of them.

Every ambipolar type `T` has an ambipolar greatest dynamic supertype `D(T)`:

• `D(Integer)` = `Number`
• `D(Rational)` = `Number`
• `D(T)` = `DynamicEntity` for dynamic entity types (the main use case)
• `D(T)` = `T` for all other types

In each case, there is a "check" function that can convert `D(T)` back to `Maybe T`.

##### Type Pattern

If `pat` is a pattern of type `T`, then `(pat: T)` is a pattern of type `D(T)`. Here's an example:

```showNumberType: Number -> Text;
showNumberType n =
case n of
(i: Integer) -> "integer: " <> toText i;
(r: Rational) -> "rational: " <> toText r;
_ -> "number: " <> toText n;
end
```
##### Check

`check` is simply the retraction function.

`check @T: D(T) -> Maybe T`

This is equivalent to

`\d -> case d of (t:T) -> Just t; _ -> Nothing end`

##### Coerce

If you're sure that the retraction will always succeed, you can use `coerce`. (If it doesn't, you'll get a run-time error.)

`coerce @T: D(T) -> T`

This is equivalent to

`\d -> case d of (t:T) -> t; _ -> error "coercion from D(T) to T failed" end`