此Haskell程序是否提供“免费定理!”的示例?

时间:2019-01-18 12:09:55

标签: haskell

关于清单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!

1 个答案:

答案 0 :(得分:7)

不,它是一类,这一事实给您一个单独的类型留出了太多的回旋余地,无法保证该公理。例如,以下替代实例进行类型检查,但违反了您的公理:

instance Category Continuant Int where
    getUI _ = 42

(完全明确地说,我们的对手可以选择例如t=Continuanta=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只能作为无限循环之类的东西来实现。

我怀疑将您想要的公理编码为只能由满足它的事物居住的类型非常困难。