关于清单1 ,要求类型级别的公理
(t a) = (t (getUI(t a)))
应该作为每个特定类型类实例的一个定理推导。
test
函数的编译是否证明类型级公理对于程序中的特定类型成立?汇编是否提供了Theorems for free!的示例?
列出1
{-# LANGUAGE MultiParamTypeClasses #-}
data Continuant a = Continuant a deriving (Show,Eq)
class UI a where
instance UI Int where
class Category t a where
getUI :: (UI a) => (t a) -> a
instance Category Continuant Int where
getUI (Continuant a) = a
-- axiom (t a) = (t (getUI(t a))) holds for given types?
test :: Int -> Bool
test x = (Continuant x) == (Continuant (getUI (Continuant x)))
其他上下文
代码基于声明如下的paper:
对于getUI的所有实现,可能需要公理(t a) =(t(getUI(t a)))成立。必须证明这适用于每个特定的类型类实例声明。对于有限类型,可以是 由列举所有可能性的程序完成。对于无限 类型,必须通过归纳证明手动完成。
清单1 是我的证明尝试。根据解决方案1,也许我错误地认为这需要Theorems for free!
答案 0 :(得分:7)
不,它是一类,这一事实给您一个单独的类型留出了太多的回旋余地,无法保证该公理。例如,以下替代实例进行类型检查,但违反了您的公理:
instance Category Continuant Int where
getUI _ = 42
(完全明确地说,我们的对手可以选择例如t=Continuant
和a=6*9
来违反公理。)这滥用了类实例化程序选择包含类型的事实。我们可以通过删除类的参数来删除该能力:
class Category t where
getUI :: UI a => t a -> a
A,这还不够。我们可以写
data Pair a = Pair a a
然后自由定理告诉我们,对于instance Category Pair
,我们必须编写以下两个定义之一:
getUI (Pair x y) = x
-- OR
getUI (Pair x y) = y
无论选择哪种方式,我们的对手都可以选择t
来向我们表明我们的公理是错误的。
Our choice Adversary's choice
getUI (Pair x y) = x t y = Pair 42 y; a = 6*9
getUI (Pair x y) = y t x = Pair x 42; a = 6*9
好的,这滥用了类实例化程序选择t
的事实。如果我们删除了该功能...?
class Category where
getUI :: UI a => t a -> a
这极大地限制了Category
的实例化器。实际上太多了:getUI
只能作为无限循环之类的东西来实现。
我怀疑将您想要的公理编码为只能由满足它的事物居住的类型非常困难。