Я манипулирую доказательствами принуждения:
data a ~=~ b where
IsCoercible :: Coercible a b => a ~=~ b
infix 0 ~=~
sym :: (a ~=~ b) -> (b ~=~ a)
sym IsCoercible = IsCoercible
instance Category (~=~) where
id = IsCoercible
IsCoercible . IsCoercible = IsCoercible
coerceBy :: a ~=~ b -> a -> b
coerceBy IsCoercible = coerce
Я могу доказать тривиально Coercible a b => forall x. Coercible (a x) (b x)
introduce :: (a ~=~ b) -> (forall x. a x ~=~ b x)
introduce IsCoercible = IsCoercible
Но не наоборот, (forall x. Coercible (a x) (b x)) => Coercible a b)
не так бесплатен:
eliminate :: (forall x. a x ~=~ b x) -> (a ~=~ b)
eliminate IsCoercible = IsCoercible
{-
• Could not deduce: Coercible a b
arising from a use of ‘IsCoercible’
from the context: Coercible (a x0) (b x0)
bound by a pattern with constructor:
IsCoercible :: forall k (a :: k) (b :: k).
Coercible a b =>
a ~=~ b,
in an equation for ‘eliminate’
-}
Я вполне уверен, что мое утверждение верно (хотя я открыт для опровержения), но у меня нет каких-либо блестящих идей о том, как доказать это в Haskell, если не считать unsafeCoerce
.