I want to define a type constructor which embodies the concept of using a type wrapper to define equality on a domain type t1
by projecting onto a domain type t2
with a function p
.
The following specific example works, where t1
= ABC
, t2
= Nat
and p
is the function abc_2_nat
:
%default total
data ABC = A | B | C
abc_2_nat : ABC -> Nat
abc_2_nat A = 1
abc_2_nat B = 1
abc_2_nat C = 2
data Projected_abc : Type where
Project_abc : ABC -> Projected_abc
Projected_abc_equals : Projected_abc -> Projected_abc -> Bool
Projected_abc_equals (Project_abc x) (Project_abc y) = abc_2_nat x == abc_2_nat y
Eq Projected_abc where
(==) = Projected_abc_equals
But, when I attempt to generalize as follows:
data Projected : t1 -> t2 -> (p: t1 -> t2) -> Type
where Project : t1 -> Projected t1 t2 p
Projected_equals : Projected t1 t2 p -> Projected t1 t2 p -> Bool
Projected_equals (Project x) (Project y) = ?hole
I get this hole:
- + Main.hole [P]
`-- phTy : Type
t2 : phTy
p : Type -> phTy
t1 : Type
x : t1
y : t1
--------------------------
Main.hole : Bool
This doesn't work because it doesn't recognise that p
is of type t1->t2
(which is what I want).
I suspect that I'm asking too much to supply the projection function as an argument to a type constructor, and somehow have the projection function available in the scope of the definition of a function whose parameters belong to the constructed type.
Is there any way I can get this to work?