gpt4 book ai didi

haskell - 如何摆脱这种歧义?

转载 作者:行者123 更新时间:2023-12-04 10:20:42 25 4
gpt4 key购买 nike

我很确定以前有人问过这个问题,但是我找不到正确的答案:

我试图消除以下示例代码片段中的歧义:

{-# 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 使用哪个实例(而不是要求它自己派生正确的类型)。

至于两者 - 在这个来自的现实世界示例中,我实际上需要两个参数 ab要独立。

再说一遍:我知道这个例子非常愚蠢,我知道 b没有在类型类的主体中使用,这是没有意义的。这是对现实世界示例的极端简化,这实际上是有道理的。真正的用例涉及类型的“可替代性” a使用类型 b然后是类型的“统一性” ab使用类型 c不幸的是要长得多。

编辑(2)

好的,对不起。我想你毕竟说服了我,我必须重构代码,以免有任何定义不明确的函数(即在其类型签名中不包含所有独立类型的函数)。不过,和你交谈真的帮助我思考了这件事。赞赏。

最佳答案

即使您删除了 bar,您的类也未定义。完全来自类。让我们假设您有以下类(class):

class FooBar a b
where
foo :: a -> a
foo = id

假设现在您想使用 foo在这个类的定义之外。
e = .... foo x .....

GHC 将提示与您的错误消息类似的错误消息,即找不到 b 的类型.仅仅是因为您的代码不提供这种类型。您的类型类声明说明了每一对类型 ab可能会得到一个实例。所以,即使 afoo 的调用中修复仍然有许多可能的实例可供选择。

函数依赖 a -> b将解决该问题,因为它指出:给定类型 a Foobar a b 可能只有一个实例.关联类型通过不使用多参数类型类来避免该问题。

关于OP的编辑:

如果你坚持有两个类型参数。那么类型类的每个方法的签名都必须包含该类的每个类型变量。没有其他办法了。

关于haskell - 如何摆脱这种歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8416186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com