“模式匹配”并在封闭类型族中递归以证明类型相等

时间:2018-08-11 17:40:56

标签: haskell type-families

假设这样的情况:

data Foo a = Foo

type family AlwaysInt a where
  AlwaysInt (Foo a) = AlwaysInt a
  AlwaysInt _       = Int

我想证明AlwaysInt a始终是Int

import Data.Type.Equality

lemma :: AlwaysInt a :~: Int
lemma = undefined

我如何证明这一点?我想对类型族定义中的每种类型进行“模式匹配”,因为我可以证明每种情况的引理,但是如何进行这种模式匹配?

丑陋的解决方法是在a上添加lemma自变量,然后在其中放置undefined或放置error消息,但这在现实生活中并不理想。

编辑:忘记实际问题

2 个答案:

答案 0 :(得分:4)

你不能证明这一点。

type family Any where {}
type family ManyFoo where
  ManyFoo = Foo ManyFoo

什么是AlwaysInt AnyAny卡住的类型,因此GHC无法减少类型族的应用。

什么是AlwaysInt ManyFoo?好吧,ManyFoo是一个无限类型,

ManyFoo = Foo (Foo (Foo ...))

因此,GHC将进入无限循环,尝试对其进行计算或尝试计算AlwaysInt ManyFoo

答案 1 :(得分:1)

:~:defined as的GADT,当a等于b时会有人居住。在这种情况下,居民称为Refl。 GHC很聪明,足以理解在这种情况下两种类型是相等的。这样编译

{-# LANGUAGE TypeFamilies, TypeOperators #-}

import Data.Type.Equality

data Foo = Foo

type family AlwaysInt a
  AlwaysInt Foo = Int
  AlwaysInt _   = Int

lemma :: AlwaysInt a :~: Int
lemma = Refl

如果将Int中的一个更改为其他类型,则由于Refl不是(something strange) :~: Int的成员,我们将收到类型错误。