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

使用数据族的类实例报错“Couldn't match expected type”排查

类型族实例中的类型匹配错误分析

问题代码

{-# LANGUAGE TypeFamilies #-}

import Data.Kind ( Type )

class Record rec where
  data Ident rec :: Type
  create :: rec -> Ident rec

newtype Person = Person { name :: String } deriving Show

instance Record Person where
  data Ident Person = String
  create p = ""

报错信息

Record.hs:13:14: error:
    • Couldn't match type: [Char]
                     with: Ident Person
      Expected: Ident Person
        Actual: String
    • In the expression: ""
      In an equation for ‘create’: create p = ""
      In the instance declaration for ‘Record Person’

问题场景

将代码中的""替换为undefined后可成功加载文件,执行:info Person会显示data instance Ident Person = String,但疑惑为何原代码中类型不匹配。

问题根源与解决方案

你误解了data Ident Person = String的核心含义:

  • 这行代码不是把Ident Person类型和标准库的String(即[Char])绑定,而是定义了一个全新的独立类型Ident Person,它只有一个无参数的构造器,这个构造器的名字恰好叫String——这个String和标准库的String类型没有任何关系。
  • create函数要求返回Ident Person类型的值,你应该写自定义的构造器名String,而非标准字符串字面量""。

修正方案1:使用自定义构造器

instance Record Person where
  data Ident Person = String
  create p = String  -- 用自定义构造器构造Ident Person类型的值

修正方案2:改用类型同义词族

如果你的真实意图是让Ident Person直接等同于标准String类型,应该把数据族(data)改成类型同义词族(type):

class Record rec where
  type Ident rec :: Type  -- 替换data为type
  create :: rec -> Ident rec

instance Record Person where
  type Ident Person = String  -- 这里才是将Ident Person定义为String的同义词
  create p = ""  -- 此时""的类型[Char]与Ident Person匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:21:00