我有一个功能foo
与一系列的约束。当然,这些约束必须出现在使用foo
的函数的签名中,所以我试图做的是将foo
约束包含在类型同义词FooCtx a b ... :: Constraint
中。作为一个例子,利用fundeps绑定约束
foo :: (A a, B b, C c, ...) => a -> b -> c
bar :: (A a, B b, C c, ...) ...
bar = ... foo ...
将成为
type FooCtx a b c ... = (A a, B b, C c, ...)
foo :: (FooCtx a b c) => a -> b -> c
bar :: (FooCtx a b c) => ...
如果所有类型的暴露这个伟大的工程。但是,我正在使用函数依赖来生成约束列表中的某些类型,并且这些类型不会出现在foo
的签名中。例如:
class Bar a b | a -> b
foo (Bar a b, ...) => a -> a
GHC不会接受type FooCtx a = (Bar a b)
因为b
未绑定的LHS。我也不能使用type FooCtx a b = (Bar a b)
,因为b
不在foo
的签名范围内。 foo
的签名应为foo :: (FooCtx a ?) => a -> a
。
一个不能令人满意的解决办法是把制约因素之一在foo
签名与FooCtx
带来fundep类型中范围:
class Bar a b | a -> b
type FooCtx a b = ...
foo (Bar a b, FooCtx a b) => a -> a
但这违背了分组的约束的目的:
在遇到这种情况之前,我认为约束同义词可以被盲目取代任意约束列表。我知道封装这样的约束的唯一方法是使用一个类,但它遭受同样的问题:class (A a, B b, C c, ...) => FooCtx a b c
在LHS上不能有任何隐藏类型。有没有其他方法可以完全收集所有这些限制?
“type FooCtx a b = ...'出现了什么问题 - 这只比'type FooCtx a = ...'长2个字符。 – user2407038 2015-03-03 04:16:56
正如我上面提到的,GHC接受你的签名,但对于'foo'的LHS我没用,因为'b'不在'foo'的签名范围内。 – crockeea 2015-03-03 04:18:58
是否有任何理由不能使用'TypeFamilies'而不是'FunctionalDependencies'? – Cirdec 2015-03-03 04:59:14