gpt4 book ai didi

haskell - 多参数类型类和非法实例声明

转载 作者:行者123 更新时间:2023-12-02 04:15:01 24 4
gpt4 key购买 nike

我制作了一个 Convertible 类的版本,如下所示:

class Convertible a b where
convert :: a -> b

instance (Convertible a b, Functor f) => Convertible (f a) (f b) where
convert = fmap convert

但是,我发现如果我想将两个转换串在一起就必须创建一个新实例,这很烦人。所以我尝试添加这个:

instance (Convertible a b, Convertible b c) => Convertible a c where
convert = convert . convert

编译器对此提示:

Variable ‘b’ occurs more often than in the instance head
in the constraint: Convertible a b
(Use UndecidableInstances to permit this)
In the instance declaration for ‘Convertible a c’
Variable ‘b’ occurs more often than in the instance head
in the constraint: Convertible b c
(Use UndecidableInstances to permit this)
In the instance declaration for ‘Convertible a c’

此时我明白为什么编译器向我提示,而且我真的不想打开 UndecidableInstances。我目前设置实例的方式是,每个 a 只有一个 Convertible a b 实例。我希望添加函数依赖 a -> b 可以缓解这个问题,但现在编译器提示仿函数实例:

Illegal instance declaration for ‘Convertible (f a) (f b)’
The coverage condition fails in class ‘Convertible’
for functional dependency: ‘a -> b’
Reason: lhs type ‘f a’ does not determine rhs type ‘f b’
Using UndecidableInstances might help
In the instance declaration for ‘Convertible (f a) (f b)’

关于如何让它发挥作用有什么想法吗?或者如果有必要的话也许有更好的设计?我想我可能只能满足于明确要采取的转换路径。

最佳答案

我认为这必须需要UndecidableInstances:

instance (Convertible a b, Convertible b c) => Convertible a c where

给定a,由于函数依赖,我们可以计算b。但是,不能保证这样的 ba 更小/更简单!它可能是例如b ~ [[a]],在这种情况下,我们将检查 Convertible a c 的问题减少为检查 Convertible [[a]] c 。这很容易导致实例搜索期间不终止,因为类参数没有减少。

相关说明:如果满足函数依赖关系,则只有一种类型b可以转换为a。在这种情况下,为什么需要传递性? a 无法转换为其他任何内容。换句话说,在传递性情况下,您需要有 c ~ b,否则您将让 a 确定 b c,违反了函数依赖性。 (我猜你毕竟并不真正想要函数依赖。)

不相关的注释:还要注意实例重叠——上面的实例看起来很麻烦。您可能还必须使用 OverlappingInstances 和/或 IncoherentInstances,这两者都会引起头痛。

关于haskell - 多参数类型类和非法实例声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34318707/

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