使用数据族的类实例报错“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
相关产品推荐
相关产品推荐

