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

如何在Haskell中指定具有多参数单射性的类型族?

解决方法

方法1:多参数类型类 + 函数依赖

如果可以重构AA类的结构,最直接的方式是把Context a、B a、C a作为显式参数加入类型类,同时用函数依赖声明这三个参数能唯一确定a:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TypeFamilies #-}

class A a where
  type Context a

-- 函数依赖 ctx b c -> a 表示:给定ctx、b、c,a是唯一的
class (A a, Context a ~ ctx) => AA ctx b c a | ctx b c -> a where
  type B a = b
  type C a = c
  problematic :: ctx -> b -> c -> a

这里Context a ~ ctx用来保证类中显式的ctx参数和A类里的关联类型Context a一致,函数依赖则强制了三个输入类型到a的唯一性约束。

方法2:TypeFamilyDependencies 扩展(GHC 8.0+)

要是想保留AA a这种单参数类的结构,可以用GHC的TypeFamilyDependencies扩展,把三个关联类型打包成一个元组类型家族,再声明这个元组到a的单射依赖:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}

class A a where
  type Context a

class A a => AA a where
  type B a
  type C a
  -- 打包三个关联类型,并声明:给定这个元组,a是唯一的
  type ABC a = (Context a, B a, C a) | (Context a, B a, C a) -> a
  problematic :: Context a -> B a -> C a -> a

这个方式不需要改动原有类的参数结构,通过新增的ABC类型家族间接实现了“Context、B、C组合唯一确定a”的约束。

约束的有效性

不管用哪种方法,只要你尝试定义两个不同的a实例,且它们的Context、B、C完全相同,GHC就会检测到依赖冲突,直接报错拒绝编译,保证了约束的有效性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:45:59