If I understood your question correctly, you want something that looks like the identity type. When we declare the type constructor _isOfType_
, we mention two Set
s (the parameter A
and the index B
) but the constructor indeed
makes sure that the only way to construct an element of such a type is to enforce that they are indeed equal (and that a
is of this type):
data _isOfType_ {ℓ} {A : Set ℓ} (a : A) : (B : Set ℓ) → Set where
indeed : a isOfType A
We can now have functions taking as arguments proofs that things are of the right type. Here I translated your requirements & assumed that I had a function f
able to combine two C
s into one. Pattern-matching on the appropriate assumptions reveals that E and F are indeed on type C
and can therefore be fed to f
to discharge the goal:
example : ∀ (A : Set₃) (B : Set₂) (C D : Set₁) (E F : Set) →
B isOfType A
→ C isOfType B → D isOfType B
→ E isOfType C → F isOfType C
→ (f : C → C → C) → C
example A B .Set D E F _ _ _ indeed indeed f = f E F
Do you have a particular use case in mind for this sort of patterns or are you coming to Agda with ideas you have encountered in other programming languages? There may be a more idiomatic way to formulate your problem.