I have a pretty typical definition of a category as such:
class Category (cat :: k -> k -> Type) where
id :: cat a a
(.) :: cat a b -> cat c a -> cat c b
Now I would like to make the Product Category so I made this GADT
data ProductCategory
(cat1 :: a -> a -> Type)
(cat2 :: b -> b -> Type)
(x :: (a, b))
(y :: (a, b))
where
MorphismProduct :: cat1 x x -> cat2 y y -> ProductCategory cat1 cat2 '(x, y) '(x, y)
Now this compiles nicely, my issue arrives when I try to make this an instance of Category. The math here is really easy, it seems like this should be a simple instance. So here is what I come up with:
instance
( Category cat1
, Category cat2
)
=> Category (ProductCategory cat1 cat2)
where
id = MorphismProduct id id
(MorphismProduct f1 f2) . (MorphismProduct g1 g2) = MorphismProduct (f1 . g1) (f2 . g2)
But this comes up with an error:
• Couldn't match type ‘a2’ with ‘'(x0, y0)’
‘a2’ is a rigid type variable bound by
the type signature for:
id :: forall (a2 :: (a1, b1)). ProductCategory cat1 cat2 a2 a2
at src/Galaxy/Brain/Prelude.hs:175:5-6
Expected type: ProductCategory cat1 cat2 a2 a2
Actual type: ProductCategory cat1 cat2 '(x0, y0) '(x0, y0)
• In the expression: MorphismProduct id id
In an equation for ‘id’: id = MorphismProduct id id
In the instance declaration for
‘Category (ProductCategory cat1 cat2)’
• Relevant bindings include
id :: ProductCategory cat1 cat2 a2 a2
(bound at src/Galaxy/Brain/Prelude.hs:175:5)
|
175 | id = MorphismProduct id id
| ^^^^^^^^^^^^^^^^^^^^^
I've spent a long while on this error and I just don't know what it is trying to communicate to me. It claims that it can't match a to '(x0, y0) but I have no idea why, it seems like it really should be able to.
What is the issue that is being encountered here? How to fix it would be nice but I would really like to know how to read this message.