`vec_ptype2()`

finds the common type for a pair of vectors, or dies trying.
It forms the foundation of the vctrs type system, along with `vec_cast()`

.
This powers type coercion but should not usually be called directly;
instead call `vec_ptype_common()`

.

# S3 method for logical vec_ptype2(x, y, ..., x_arg = "", y_arg = "") # S3 method for integer vec_ptype2(x, y, ..., x_arg = "", y_arg = "") # S3 method for double vec_ptype2(x, y, ..., x_arg = "", y_arg = "") # S3 method for complex vec_ptype2(x, y, ..., x_arg = "", y_arg = "") # S3 method for character vec_ptype2(x, y, ..., x_arg = "", y_arg = "") # S3 method for raw vec_ptype2(x, y, ..., x_arg = "", y_arg = "") # S3 method for list vec_ptype2(x, y, ..., x_arg = "", y_arg = "") vec_ptype2(x, y, ..., x_arg = "", y_arg = "") vec_default_ptype2(x, y, ..., x_arg = "", y_arg = "")

x, y | Vector types. |
---|---|

... | These dots are for future extensions and must be empty. |

x_arg, y_arg | Argument names for |

vctrs thinks of the vector types as forming a partially ordered set, or poset. Then finding the common type from a set of types is a matter of finding the least-upper-bound; if the least-upper-bound does not exist, there is no common type. This is the case for many pairs of 1d vectors.

The poset of the most important base vectors is shown below:
(where datetime stands for `POSIXt`

, and date for `Date`

)

`vec_ptype2()`

dispatches on both arguments. This is implemented by having
methods of `vec_ptype2()`

, e.g. `vec_ptype2.integer()`

also be S3 generics,
which call e.g. `vec_ptype2.integer.double()`

. `vec_ptype2.x.y()`

must
return the same value as `vec_ptype2.y.x()`

; this is not enforced
for reasons of efficiency, but should be tested.

`vec_ptype2()`

are not inherited, classes must explicitly implement
the methods. There are two reasons for this:

The coercion hierarchy is often different from a class hierarchy. For instance the richer type between a tibble and a data frame is a tibble. Grouped data frames inherit from tibble, and so would by default inherit from tibble's

`vec_ptype2()`

method if inheritance was allowed. The method would then indicate that the richer type between a grouped data frame and a data frame is a tibble, which is wrong.`vec_ptype2()`

should be symmetric, i.e. it should return the same type no matter the order of the inputs. With inheritance, this isn't the case when two classes have a common parent class. For instance the richer type between a tsibble and a tibble is tsibble. Similarly, grouped data frames are a richer type than tibble. Both of these classess have tibble as common parent class. With inheritance,`vec_ptype2(tsibble, gdf)`

would return a tsibble via the tsibble-tibble method.`vec_ptype2(gdf, tsibble)`

would return a grouped data frame via the gdf-tibble method.

Because of the way double dispatch is implemented, `NextMethod()`

does not work inside `vec_ptype2()`

methods.

See `vignette("s3-vector")`

for full details.