价值的平等不会依赖于这些价值而延续到类型;我错过了什么吗?

时间:2016-09-16 18:20:24

标签: dependent-type idris

我试图在Idris中实现尽可能多的System F(多态lambda演算)。我现在面临一个问题,我想用一个例子来证明:

data Foo = Bar Nat

Eq Foo where
 (Bar _) == (Bar _) = True

data Baz: Foo -> Type where
 Quux: (n: Nat) -> Baz (Bar n)

Eq (Baz f) where
 (Quux a) == (Quux b) = ?todo

如您所见,任何两个Foo值都相等。我现在希望能够在Baz f上定义相等性时使用这一事实:Quux a类型Baz (Foo a)Quux b类型Baz (Foo b)和{{ 1}}和Foo a是平等的,所以我的直觉是这应该有效。但编译器拒绝它,说Foo bBaz (Foo a)之间的类型不匹配。

有没有办法让这项工作?这个问题阻止我实现alpha等价。

2 个答案:

答案 0 :(得分:1)

不幸的是,我对系统F和alpha等效性几乎一无所知,所以请用一粒盐。但是,在您发布的特定情况中解决问题的一种方法是:

data Foo = Bar

bar: Nat -> Foo
bar _ = Bar

Eq Foo where
 Bar == Bar = True

data Baz: Foo -> Type where
 Quux: (n: Nat) -> Baz (bar n)

Eq (Baz f) where
 (Quux a) == (Quux b) = ?todo

据我了解,Eq个实例用于运行时的等式检查。没有咨询他们以检查两种类型是否统一。

您希望所有Foo个实例在类型级别上统一,因此实际上只能有一个;我们只需称它为Bar。您在代码中使用的该名称的数据构造函数已降级为函数bar,只返回Foo个唯一Bar实例Nat。< / p>

Eq的{​​{1}}实施现在更加微不足道了(虽然在这种情况下不再需要),Foo现在使用Quux代替bar因此,它创建的所有Bar实例实际上都共享相同的类型Baz

答案 1 :(得分:1)

为什么不为异质平等定义另一个运算符并使用它呢?

module Main

infix 5 ~=

interface HEq a b where
  (~=) : a -> b -> Bool

-- This will make ~= work as replacement for ==
Eq a => HEq a a where
  (~=) = (==)

data Foo = Bar Nat

Eq Foo where
  (Bar _) == (Bar _) = True

data Baz : Foo -> Type where
  Quux : (n : Nat) -> Baz (Bar n)

HEq (Baz a) (Baz b) where
  (Quux x) ~= (Quux y) = True -- do whatever you want here

main : IO Unit
main = do
  putStrLn $ show $ 5 ~= 5 -- prints True
  putStrLn $ show $ 5 ~= 6 -- prints False
  putStrLn $ show $ (Quux 10) ~= (Quux 20) -- prints True