【发布时间】:2012-01-15 00:22:36
【问题描述】:
我很确定以前有人问过这个问题,但是我找不到正确的答案:
我试图消除以下示例代码 sn-p 中的歧义:
{-# LANGUAGE MultiParamTypeClasses #-}
class FooBar a b where
foo :: a -> a
foo = id
bar :: a -> a
bar = foo -- ERROR AT THIS LINE
我收到如下错误消息:
Ambiguous type variable `b0' in the constraint:
(FooBar a b0) arising from a use of `foo'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: foo
In an equation for `bar': bar = foo
这是可以理解的。但是请注意,我实际上无法遵循编译器的建议并修复有问题的类型变量:foo 在其类型签名中不包含b 类型变量。这也不起作用:
bar = (foo :: FooBar a b => a -> a) -- ERROR, the same error message
即使启用了-XScopedTypeVariables 也不行。
如何告诉 GHC 使用哪个 FooBar?有没有可能?
编辑
以下一些答案:是的,我听说过函数依赖和关联类型。
至于功能依赖——我正在寻找一种方法来明确告知 GHC 使用哪个实例(而不是要求它自己派生正确的类型)。
至于两者 - 在这个来自现实世界的示例中,我实际上需要两个参数 a 和 b 是独立的。
再说一遍:我知道这个例子非常愚蠢,我知道b 没有用在类型类的主体中,这没有任何意义。这是对现实世界示例的极端简化,这实际上是有道理的。真正的用例涉及使用 b 类型的 a 类型的“可替代性”,然后使用 c 类型的 a 和 b 类型的“统一性”,不幸的是要长得多。
编辑(2)
好的,抱歉。我想你毕竟说服了我,我必须重构代码,以免有任何定义不明确的函数(即在其类型签名中不包含所有独立类型的函数)。不过,和你交谈真的帮助我思考了这件事。赞赏。
【问题讨论】:
-
您能解释一下为什么要这样做吗?
FooBar的实现只依赖a,不依赖b,那提b有什么意义呢? -
@lbolla 是的,我可以解释一下,但是这将花费这里所有代码 sn-ps 的两倍,并且涉及的不是一个而是 3 个不同的类型类。恐怕你必须相信我。这只是一个示例,可以使用需要
a和b的其他方法进行扩展。 -
@julkiewicz:我已经编辑了我的答案来回答你的编辑。
标签: haskell functional-programming ghc ambiguity type-systems