假设这样的情况:
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
消息,但这在现实生活中并不理想。
编辑:忘记实际问题
答案 0 :(得分:4)
你不能证明这一点。
type family Any where {}
type family ManyFoo where
ManyFoo = Foo ManyFoo
什么是AlwaysInt Any
? Any
是卡住的类型,因此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
的成员,我们将收到类型错误。