我正在学习Type Families并试图理解为什么我在特定情况下没有得到编译时错误。
我的类型系列定义如下:
type family Typ a b :: Constraint
type instance Typ (Label x) (Label y) = ()
我有两个功能如下:
func1 :: (Typ (Label "la") (Label "lb")) => Label "la" -> Label "lb" -> String
func1 = undefined
func2 :: (Typ (Label "la") String) => Label "la" -> String -> String
func2 = undefined
这两个函数都编译正常。
当我尝试查看func1
的类型时,我会得到正确的签名。但是,当我尝试查看func2
的类型时,我得到错误以下错误
无法推断(Typ(Label“la”)String)
为什么会这样?有人可以帮我理解吗?
答案 0 :(得分:3)
我能够使用Label
的定义复制您所描述的内容:
import GHC.TypeLits (Symbol)
data Label (a :: Symbol)
并补充说:
type instance Typ (Label x) String = ()
然后提供func2
修改强>
对不起,我误解了这个问题。我的理解是,检查约束的可满足性将推迟到实际使用func2
,因为稍后可以添加实例。
例如,添加:
func3 = func2 (undefined :: Label "la") ""
导致它在编译时失败。
我理解它的方式是func2
说,如果你给我Label "la"
和String
,Typ (Label "la") String
的实例是在当时的范围,我会给你一个String
。但是func2
并不需要在范围内有一个实例来了解如果它拥有它将会对它做什么。