Coq: a single notation for multiple constructors

Question

Is it possible to define a single notation for multiple constructors in Coq? If the constructors differ by their argument types, they might be inferrable from them. A minimal (non-)working example:

Inductive A : Set :=
  a | b | c : C -> A | d : D -> A
  with C : Set := c1 | c2
  with D : Set := d1 | d2.

Notation "' x" := (_ x) (at level 19).
' c1 : ?T@{x:=c1} where ?y : [ |- forall x : C, ?T] ?T : [x : C |- Type]

In this case, constructor inference doesn't work. Maybe there's another way to specify a constructor as a variable?

Answer (Daniel Schepler)

You can create a typeclass with the constructors as instances and let the instance resolution mechanism infer the constructor to call for you:

Class A_const (X : Type) : Type :=
  a_const : X -> A.
Instance A_const_c : A_const C := c.
Instance A_const_d : A_const D := d.

a_const c1 : A
a_const d2 : A

By the way, with Coq 8.5, if you really want a notation ' x to result in the exact constructor applied to x, rather than e.g. @a_const C A_const_c c1, then you can use ltac-terms to accomplish that:

This notation contains Ltac expressions: it will not be used for printing. [non-reversible-notation,parsing]
c c1 : A
d d2 : A

A: Indeed; depending on the particular application using a Canonical Structure could work very well here too.

Answer (Daniel Schepler)

In fact, the idea of using an ltac-term leads to an entirely different solution from the other one I posted:

This notation contains Ltac expressions: it will not be used for printing. [non-reversible-notation,parsing]
c c1 : A
d d2 : A

(Here the eval hnf part lets it work even if the type of the argument isn't syntactically equal to C or D, but it does reduce to one of them.)