How to understand p r -> t
and p t -> r
in PFunctor p r t | p r -> t, p t -> r
?
https://github.com/ekmett/categories/blob/4a02808d28b275f59d9d6c08f0c2d329ee567a97/old/src/Control/Categorical/Bifunctor.hs#L30
In my understanding, p r -> t
means p r
can determain t
's type. And p t
can determain r
's type.
For example, p :: (,)
r :: (->)
t :: (->)
. Why p r :: ((->),)
can determain t :: (->)
's type? Or when will ghc throw compiling error if not fulfilling these two constraints?
Or when will ghc throw compiling error if not fulfilling these two constraints?
If you try to declare an instance that violates these constraints, that instance will be flagged. For example,
instance PFunctor (,) (->) (->)
by itself is fine, and
instance PFunctor (,) (->) Either
by itself would be fine, but if you have both:
instance PFunctor (,) (->) (->)
instance PFunctor (,) (->) Either
then you will get a complaint:
test.hs:4:10: error: [GHC-46208]
Functional dependencies conflict between instance declarations:
instance PFunctor (,) (->) (->) -- Defined at test.hs:4:10
instance PFunctor (,) (->) Either -- Defined at test.hs:5:10
|
4 | instance PFunctor (,) (->) (->)
| ^^^^^^^^^^^^^^^^^^^^^^
In this case, the error happens because p ~ (,)
and r ~ (->)
together don't uniquely determine t
-- which could be either (->)
or Either
.