假设我有一个多参数类型类:
class B b => C a b | a -> b where
getB :: a -> (T, b)
Run Code Online (Sandbox Code Playgroud)
然后我想要一个功能:
f :: C a b => a -> c
f = g . getB
Run Code Online (Sandbox Code Playgroud)
它使用其他功能g :: B b => (T, b) -> c
和getB
,因此一个实例C a b
是必要的.
(免责声明:真正的问题要复杂得多,上面提到的只是简化版.)
问题是,鉴于功能依赖性C a b | a -> b
,我们知道b
可以完全决定a
,所以理论上我应该可以不提b
类型f
(因为它不在别处使用,但在实例中C a b
),但我没有发现任何实现这一目标的方法.
还要注意,由于B b
类中存在约束C
,我认为我不能使用TypeFamilies扩展,因为它的语法无法使类型约束生效B b
.
那么有什么办法可以隐藏b
这个函数用户的实现细节(不相关的类型参数)f
?
使用TypeFamilies
,您可以重写C
为单参数类,如下所示:
class B (BOf a) => C a where
type BOf a :: *
getB :: a -> (T, BOf a)
Run Code Online (Sandbox Code Playgroud)
这为您提供了更好看的约束f
:
f :: C a => a -> c
Run Code Online (Sandbox Code Playgroud)
(遗憾的是)无法省略多参数类的参数以获得类似的结果.