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

如何复用带函数依赖的类型类实现GetType类型级函数?

错误信息翻译

关联类型声明的右侧提到了超出作用域的变量‘a’
所有此类变量必须在左侧绑定

问题分析

你写的CanGetType类存在两个核心问题:

  1. 类参数b完全多余——MyClass已经通过函数依赖name -> result保证了每个name对应唯一的result,不需要额外把结果类型作为类参数声明。
  2. 关联类型的定义不符合规则:类中声明的是GetType a,但实例里的GetType name = result没有正确对应类参数的绑定逻辑,导致GHC判定变量作用域异常。

正确实现方案

方案一:使用开放类型家族(推荐)

不需要额外定义辅助类,直接通过类型家族结合MyClass的约束实现类型级函数:

{-# LANGUAGE TypeFamilies, FunctionalDependencies, ConstraintKinds #-}
import GHC.TypeLits (KnownSymbol)

class (KnownSymbol name) => MyClass name result | name -> result
instance MyClass "something" Int

-- 定义类型级函数GetType
type family GetType name :: Type

-- 利用MyClass的约束推导结果类型
type instance GetType name = result
  where
    constraint MyClass name result

方案二:调整辅助类写法

如果更倾向于用类实现,可以去掉多余参数,让辅助类直接复用MyClass的约束:

{-# LANGUAGE TypeFamilies, FunctionalDependencies, FlexibleInstances #-}
import GHC.TypeLits (KnownSymbol)

class (KnownSymbol name) => MyClass name result | name -> result
instance MyClass "something" Int

-- 辅助类仅保留输入类型参数
class KnownSymbol a => CanGetType a where
  type GetType a :: Type

-- 复用MyClass实例实现类型推导
instance MyClass name result => CanGetType name where
  type GetType name = result

验证示例

通过类型签名可以验证效果:

test :: GetType "something"
test = 42 -- 类型为Int,编译通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:43:11