The problem, as indicated, cannot be solved, since the fact that p is equal to Representational (or even Phantom ) does not mean that p (Fix pa) is representative. Here's a counterexample:
data NF ab where NF :: NF a () instance Representational NF where rep _ = Coercion
It is clear that NF a never representative; we cannot realize
rep :: Coercion xy -> Coercion (NF ax) (NF ay)
(regardless of the choice of a ), since NF ax populated only when x ~ () .
Therefore, we need a more refined notion of a representative bifuctor to make this idea reasonable. unsafeCoerce almost certainly necessary for its implementation in any case, because digging through an endless chain of Coercion will take an infinite amount of time, and Coercion cannot be matched lazily.
One (maybe valid?) Concept that I just suggested on GitHub :
class Birepresentational t where birep :: Coercion pq -> Coercion ab -> Coercion (tpa) (tqb) instance Birepresentational f => Representational (Fix f) where rep (x :: Coercion ab) = (birep :: forall pqxy . Coercion pq -> Coercion xy -> Coercion (fpx) (fqy)) (unsafeCoerce x :: Coercion (Fix fa) (Fix fb)) x `seq` unsafeCoerce x
The point of forcing the birep application is (I hope) to make sure that it actually terminates, and therefore its type can be trusted.
source share