Haskell 存在数据族时的类型(in)等式

Haskell 存在数据族时的类型(in)等式,haskell,dependent-type,type-families,Haskell,Dependent Type,Type Families,我有一个类型族,它确定某个对象是否位于类型级别列表的开头 type family AtHead x xs where AtHead x (x ': xs) = True AtHead y (x ': xs) = False 我想构造这个结果的单例代表。这适用于简单类型的列表 data Booly b where Truey :: Booly True Falsey :: Booly False test1 :: Booly (AtHead Char [Char

我有一个类型族,它确定某个对象是否位于类型级别列表的开头

type family AtHead x xs where
    AtHead x (x ': xs) = True
    AtHead y (x ': xs) = False
我想构造这个结果的单例代表。这适用于简单类型的列表

data Booly b where
    Truey :: Booly True
    Falsey :: Booly False

test1 :: Booly (AtHead Char [Char, Int])
test1 = Truey
test2 :: Booly (AtHead Int [Char, Int])
test2 = Falsey
但我真正想做的是为索引的
数据族的成员列表构建这个值。(实际上,我正试图根据元素的类型从
ID
s的异构列表中投影元素。)

当我们要查找的
ID
位于列表的最前面时,这种方法就起作用了

test3 :: Booly (AtHead (ID User) [ID User, Char])
test3 = Truey
但它在其他方面失败了

test4 :: Booly (AtHead (ID User) [Int, ID User])
test4 = Falsey

    Couldn't match type ‘AtHead (ID User) '[Int, ID User]’
                  with ‘'False’
    Expected type: Booly (AtHead (ID User) '[Int, ID User])
      Actual type: Booly 'False
    In the expression: Falsey
    In an equation for ‘test4’: test4 = Falsey
athad(ID User)][Int,ID User]
'False
不统一。看起来GHC不愿意做出
ID User
Int
不相等的判断,即使
ID
是一个内射
数据族(因此原则上只等于(简化为)
ID User

我对约束求解器会接受什么和不会接受什么的直觉相当薄弱:我觉得这应该编译。有人能解释为什么我的代码不进行类型检查吗?有没有办法诱使GHC接受它,也许是通过证明一个定理?

事实证明这是一个错误。修复程序已经在GHC head中,应该在下一个即将发布的版本中(GHC 8.0.1和7.10.3)


除此之外,@luqui关于新类型包装器的建议似乎是最简单的选择。

我知道GHC对内射数据族不太好。制作包装有时是可行的,例如,
newtype ID'a=ID'(ID a)
。在我看来,这可能是一个GHC错误。这些类型应该是“肯定不同”(GHC技术术语)…@rjanJohansen感谢您的报告,我已经在这个问题上抄送了自己@luqui的
newtype
功能确实有效,但不是很好:((只是一个术语说明。
ID User
Int
不相等的属性是生成性,而不是内射性。数据族自动生成和内射,但内射类型族
ID'
仍然可以满足
ID'User=Int
test4 :: Booly (AtHead (ID User) [Int, ID User])
test4 = Falsey

    Couldn't match type ‘AtHead (ID User) '[Int, ID User]’
                  with ‘'False’
    Expected type: Booly (AtHead (ID User) '[Int, ID User])
      Actual type: Booly 'False
    In the expression: Falsey
    In an equation for ‘test4’: test4 = Falsey