You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何GHC无法解析此类型族实例?

GHC类型族实例类型匹配失败的原因

问题场景

以下代码中,尽管已经声明了type instance Obj Hask = *,GHC仍拒绝通过Arr Hask的类型实例声明,报错提示无法匹配Obj Hask和*:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}

module Minimal where

type family Obj t :: *

type family Arr t :: Obj t -> Obj t -> *

data Hask

type instance Obj Hask = *

type instance Arr Hask = (->)

对应的报错信息:

Minimal.hs:15:26: error:
    • Couldn't match kind ‘Obj Hask’ with ‘*’
      Expected kind ‘Obj Hask -> Obj Hask -> *’,
        but ‘(->)’ has kind ‘* -> * -> *’
    • In the type ‘(->)’
      In the type instance declaration for ‘Arr’
   |
15 | type instance Arr Hask = (->)
   |                          ^^^^

然而,通过StandaloneKindSignatures扩展定义中间类型Function后,代码可以正常编译:

{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}

module Minimal where

type family Obj t :: *

type family Arr t :: Obj t -> Obj Hask -> *

data Hask

type instance Obj Hask = *

type Function :: Obj Hask -> Obj Hask -> *
type Function = (->)

type instance Arr Hask = Function

原因解析

核心问题在于GHC在检查类型族实例的等式时,不会自动展开右侧的类型族实例来进行kind匹配:

  1. 当直接写type instance Arr Hask = (->)时,GHC首先会根据Arr的声明,要求右侧的类型必须具有Obj Hask -> Obj Hask -> *的kind。
  2. 此时GHC不会主动将Obj Hask展开为*(尽管我们已经定义了对应的实例),它只会把Obj Hask当作一个尚未解析的kind变量,因此无法和(->)的* -> * -> *kind匹配,最终报错。

而使用中间类型Function的方式之所以可行,是因为:

  • 显式的独立类型签名type Function :: Obj Hask -> Obj Hask -> *强制GHC先完成Obj Hask的展开(替换为*),验证(->)的* -> * -> *kind是否符合要求。
  • 当后续将Arr Hask赋值为Function时,GHC只需要检查Function的kind是否匹配Arr t的要求——这一步已经在定义Function时完成,因此不会再触发kind不匹配的错误。

简单来说,独立类型签名相当于给GHC一个明确的信号,让它先完成类型族实例的展开和验证,而不是直接在类型族实例等式中进行未展开的kind对比。

内容的提问来源于stack exchange,提问作者rampion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:33:19