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