Sri*_*aic 9 haskell typeclass functional-dependencies type-level-computation
我有一个类型类,看起来有点像以下内容:
class Foo a b | a -> b where
f :: a -> Bool
g :: b -> Bool
h :: a -> b -> Bool
Run Code Online (Sandbox Code Playgroud)
或者至少这些对我的问题很重要。此类没有编译,并且有充分的理由。此类的问题是,我可以(如果愿意)执行以下操作:
instance Foo () Bool where
f x = True
g y = y
h x y = False
instance Foo ((), ()) Bool where
f x = True
g y = not y
h x y = False
Run Code Online (Sandbox Code Playgroud)
现在,如果我打电话g True给每个实例,有两个单独的结果。编译器意识到了这种可能性,并告诉我我的类型类不好。
我的问题是依赖性| a -> b不是我的意思。我不只是意味着你可以找到a从b,还以为你能找到b的a。也就是说,每种类型都只能Foo与另一种类型成为成员,因此我们可以给一个类型查找另一种类型。或者换一种说法,依赖关系是双向的。这种功能依赖性会阻止我Bool出现在两个单独的实例中,因为第一个参数可以从第二个参数派生,而第二个参数可以从第一个参数派生。
但是我不知道如何向编译器表达这个想法。
如何创建双向功能依赖项?或者,更有可能的是,有一种方法可以重新定义我的类型类,以获取可以替代双向功能依赖项的东西吗?
和之间的双向依赖关系可以表示为两个功能依赖关系和,例如:aba -> bb -> a
class Foo a b | a -> b, b -> a where
f :: a -> Bool
g :: b -> Bool
h :: a -> b -> BoolRun Code Online (Sandbox Code Playgroud)
因此,这里a功能依赖于b和b功能依赖于a。
instance但是对于您的,这当然会引发错误,因为现在您为定义了两个不同a的b ~ Bool。这将引发如下错误:
file.hs:6:10: error:
Functional dependencies conflict between instance declarations:
instance Foo () Bool -- Defined at file.hs:6:10
instance Foo ((), ()) Bool -- Defined at file.hs:11:10
Failed, modules loaded: none.Run Code Online (Sandbox Code Playgroud)
由于函数依赖的,你只能定义一个a为b ~ Bool。但这可能恰恰是您要寻找的东西:一种防止Foo为同一个a或同一个定义两次的机制b。