【发布时间】:2019-11-09 20:22:14
【问题描述】:
我正在处理强制证明:
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。
【问题讨论】:
-
换句话说...你在问 Haskell 类型级函数是否满足功能扩展性...
-
声明可能既不可证明也不可证明。公理
forall a b. (forall x. a x ~=~ b x) -> a ~=~ b很可能与类型系统一致(不可证伪;如果你用unsafeCoerce承认它不会出错),但它可能无法证明。 -
Safe Zero-cost Coercions for Haskell 在第 6 页上有完整的规则(此链接上的 PDF 第 7 页)。
Co_Inst是唯一适用于所有量化的东西的规则,而且似乎不是特别有用。我怀疑可以在不破坏健全性的情况下添加这样的规则。另一个明显缺失的规则(这也可以让你到达你需要去的地方)是一个说如果一个数据类型的所有字段都可以与另一个强制转换,则该类型本身可以与另一个强制转换。