Linters about type classes #
This file defines several linters checking the correct usage of type classes and the appropriate definition of instances:
instance_priority
ensures that blanket instances have low priority.has_nonempty_instances
checks that every type has anonempty
instance, aninhabited
instance, or aunique
instance.impossible_instance
checks that there are no instances which can never apply.incorrect_type_class_argument
checks that only type classes are used in instance-implicit arguments.dangerous_instance
checks for instances that generate subproblems with metavariables.fails_quickly
checks that type class resolution finishes quickly.class_structure
checks that everyclass
is a structure, i.e.@[class] def
is forbidden.has_coe_variable
checks that there is no instance of typehas_coe α t
.inhabited_nonempty
checks whether[inhabited α]
arguments could be generalized to[nonempty α]
.decidable_classical
checks propositions for[decidable_... p]
hypotheses that are not used in the statement, and could thus be removed by usingclassical
in the proof.linter.has_coe_to_fun
checks whether necessaryhas_coe_to_fun
instances are declared.linter.check_reducibility
checks whether non-instances with a class as type are reducible.
There are places where typeclass arguments are specified with implicit {}
brackets instead of
the usual []
brackets. This is done when the instances can be inferred because they are implicit
arguments to the type of one of the other arguments. When they can be inferred from these other
arguments, it is faster to use this method than to use type class inference.
For example, when writing lemmas about (f : α →+* β)
, it is faster to specify the fact that α
and β
are semiring
s as {rα : semiring α} {rβ : semiring β}
rather than the usual
[semiring α] [semiring β]
.
Certain instances always apply during type-class resolution. For example, the instance
add_comm_group.to_add_group {α} [add_comm_group α] : add_group α
applies to all type-class
resolution problems of the form add_group _
, and type-class inference will then do an
exhaustive search to find a commutative group. These instances take a long time to fail.
Other instances will only apply if the goal has a certain shape. For example
int.add_group : add_group ℤ
or
add_group.prod {α β} [add_group α] [add_group β] : add_group (α × β)
. Usually these instances
will fail quickly, and when they apply, they are almost always the desired instance.
For this reason, we want the instances of the second type (that only apply in specific cases) to
always have higher priority than the instances of the first type (that always apply).
See also #1561.
Therefore, if we create an instance that always applies, we set the priority of these instances to 100 (or something similar, which is below the default value of 1000).