如何用newtype实现带提升构造器的递归类型同义词?
解决递归类型同义词的替代方案(Haskell)
首先要明确你混淆了值级别和类型级别的构造器使用:单引号'标记的是DataKinds扩展下的类型级别构造器,而newtype的字段需要的是值级别的类型,这是你代码报错的核心原因。下面分场景给出解决方案:
场景1:定义值级别的递归类型
如果你的需求是创建一个值级别的自引用类型,直接用普通的newtype/data即可,不需要类型级别构造器(单引号):
-- 先定义值级别的基础类型和参数化构造器 data WorldModel a b c = WorldModel a b c newtype HereParameterised w = HP w -- 合法的递归newtype,和`newtype Rec = Rec (Maybe Rec)`逻辑一致 newtype PlainWorldModel = PWM (WorldModel Some Instantiation (HereParameterised PlainWorldModel))
这里的Some和Instantiation需要是你预先定义好的具体类型(比如Int、String)。
场景2:定义类型级别的递归类型
如果你的需求是在类型层面定义自引用的WorldModel实例,需要用递归类型族,但要注意递归必须有终止条件(否则类型检查器会因为无限展开报错):
{-# LANGUAGE DataKinds, TypeFamilies #-} -- 值级别的WorldModel,通过DataKinds提升为类型级别构造器 data WorldModel a b c = WorldModel a b c -- 定义基础类型和参数化类型族 type Some = Int type Instantiation = String type family HereParameterised (w :: WorldModel Type Type Type) :: Type where HereParameterised ('WorldModel _ _ c) = c -- 示例:提取第三个参数作为终止条件 -- 递归类型族定义自引用类型 type family PlainWorldModel :: WorldModel Type Type Type where PlainWorldModel = 'WorldModel Some Instantiation (HereParameterised PlainWorldModel)
是否需要singletons库?
- 如果你只需要值级别的递归:完全不需要。
- 如果你需要在值级别和类型级别之间建立精确对应(比如要操作一个值,其类型严格匹配类型层面的递归定义):singletons库可以自动生成单例类型和转换函数,避免手动编写大量重复的单例代码。示例:
{-# LANGUAGE TemplateHaskell, DataKinds, TypeFamilies, Singletons #-} import Data.Singletons.TH -- 用singletons模板自动生成类型级别和值级别的对应 singletons [d| data WorldModel a b c = WorldModel a b c deriving (Show) newtype HereParameterised w = HP w deriving (Show) |] -- 类型级别递归定义 type family PlainWorldModel :: WorldModel Type Type Type where PlainWorldModel = 'WorldModel 'Int 'String ('HP PlainWorldModel) -- 值级别单例,对应类型层面的PlainWorldModel newtype PlainWorldModelVal = PWMV (Sing PlainWorldModel)
内容的提问来源于stack exchange,提问作者PrettyPrincessKitty FS
相关产品推荐
相关产品推荐

