Haskell中箭头类型(->)的Kind是什么?为何支持unlifted types?
关于Haskell箭头类型
(->)的Kind多态性问题 你看到的GHCi输出其实是简化后的结果——(->)本质上是Kind多态的,并非只能作用于*(lifted类型)。
核心原因
GHC的类型系统里,*只是TYPE LiftedRep的别名,而 unlifted类型比如Int#的Kind是TYPE IntRep(属于TYPE r家族)。箭头类型(->)的真实Kind是多态的,它可以接受任意TYPE r类型作为参数,而不是局限于*。
GHCi显示简化的原因
默认情况下,GHCi的:k命令会把多态Kind实例化为最常用的场景——也就是所有参数都是lifted类型(*)的情况,所以你看到的是(->) :: * -> * -> *。如果开启PolyKinds扩展,就能看到它的真实多态Kind:
ghci> :set -XPolyKinds ghci> :k (->) (->) :: forall k1 k2. k1 -> k2 -> *
(注:更精确地说,在GHC的核心类型系统中,箭头的Kind是TYPE r1 -> TYPE r2 -> TYPE (FunRep r1 r2),但用户层面用PolyKinds看到的多态形式已经足够解释你的困惑。)
为什么(->) Int#合法
当你把(->)作用于Int#(TYPE IntRep)时,它的第一个参数被实例化为TYPE IntRep,剩下的部分就是接受一个*类型并返回*类型,所以GHCi显示(->) Int# :: * -> *——这完全符合它的多态Kind定义。
内容的提问来源于stack exchange,提问作者Holz
相关产品推荐
相关产品推荐

