亲切的签名和类型系列

时间:2017-07-31 22:29:41

标签: haskell types

我希望

type family Rep a

type family Rep :: * -> *

是一样的,但似乎存在差异

type family   Rep a
type instance Rep Int  = Char
-- ok

type family   Rep :: * -> *
type instance Rep Int  = Char
-- Expected kind * -> *, but got 'Int' instead

我是否只是偶然发现了一个Haskell扩展错误,还是有一些指向这种行为?

1 个答案:

答案 0 :(得分:13)

是的,有一个微妙的区别。

粗略地说,type family F a :: *->*表示,F Int是一个内射类型的构造函数,如[]Maybe。这可以被编译器利用,编译器可以键入以下代码:

type family F a :: * -> *

-- these three examples can be removed / changed, if wished
type instance F Int = []
type instance F Char = Maybe
type instance F Bool = (,) String

foo :: (F Int a :~: F Int b) -> (a :~: b)
foo Refl = Refl

要检查以上内容,编译器利用了这一事实 F Int a ~ F Int b暗示a ~ b,它来自注入。

相反,声明type family F a b :: *并不能确保F Int的注意力,因为以下内容变得合法。

type family F a b :: *
type instance F Int a = ()