gpt4 book ai didi

haskell - 有趣的类型!解析多个实例声明

转载 作者:行者123 更新时间:2023-12-04 16:32:07 25 4
gpt4 key购买 nike

我正在尝试编写一些 Haskell 代码,其中有多种数据类型,每种数据类型都可以有多种实现。为此,我将每个数据类型定义为 class其方法是相关的构造器和选择器,然后根据给定的构造器和选择器实现对该类成员的所有操作。

例如,也许 A是一个多项式类(使用方法 getCoefficientsmakePolynomial ),它可以表示为 SparsePolyDensePolyB是一个复数类(具有方法 getRealgetImagmakeComplex ),可以表示为 ComplexCartesianComplexPolar .

我在下面复制了一个最小的例子。我有两个类AB每个都有一个实现。我想把两个类的所有实例都变成 Num 的实例自动(这需要 FlexibleInstancesUndecidableInstances 类型扩展)。当我只有 A 之一时,这很好用或 B ,但是当我尝试使用两者进行编译时,出现以下错误:

Duplicate instance declarations:
instance [overlap ok] (A a, Num x, Show (a x), Eq (a x)) =>
Num (a x)
-- Defined at test.hs:13:10-56
instance [overlap ok] (B b, Num x, Show (b x), Eq (b x)) =>
Num (b x)
-- Defined at test.hs:27:10-56

我想“重复实例声明”消息是因为可以将数据类型设为 A 的实例。和 B .我希望能够向编译器 promise 我不会这样做,或者在类型是两个类的实例的情况下可能指定要使用的默认类。

有没有办法做到这一点(也许是另一种类型的扩展?)或者这是我遇到的问题吗?

这是我的代码:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}

class A a where
fa :: a x -> x
ga :: x -> a x

data AImpl x = AImpl x deriving (Eq,Show)

instance A AImpl where
fa (AImpl x) = x
ga x = AImpl x

instance (A a, Num x, Show (a x), Eq (a x)) => Num (a x) where
a1 + a2 = ga (fa a1 + fa a2)
-- other implementations go here


class B b where
fb :: b x -> x
gb :: x -> b x

data BImpl x = BImpl x deriving (Eq,Show)

instance B BImpl where
fb (BImpl x) = x
gb x = BImpl x

instance (B b, Num x, Show (b x), Eq (b x)) => Num (b x) where
-- implementations go here

编辑:为了让自己清楚,我并没有尝试使用这种技术编写任何实用的代码。我这样做是为了帮助自己更好地理解类型系统和扩展。

最佳答案

你问题的这一部分

I suppose that the 'duplicate instance declarations' message is because a data type could be made an instance of both A and B. I want to be able to make a promise to the compiler that I won't do that, or possibly specify a default class to use in the case that a type is an instance of both classes.



是不正确的。其实是因为你写了两个实例,
instance Num (a x)
instance Num (b x)

编译器无法区分(请参阅@hammar 评论中的链接,为了区分实例声明,类上下文不计算在内)。

一种解决方案是添加见证类型。
{-# LANGUAGE FlexibleInstances, FlexibleContexts, UndecidableInstances, OverlappingInstances #-}

data AWitness

data AImpl witness x = AImpl x deriving (Eq,Show)

instance A (AImpl AWitness) where
fa (AImpl x) = x
ga x = AImpl x

instance (A (a AWitness), Num x, Show (a AWitness x), Eq (a AWitness x)) => Num (a AWitness x) where
a1 + a2 = ga (fa a1 + fa a2)

编译器可以使用见证类型来区分您的实例声明。

关于haskell - 有趣的类型!解析多个实例声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10015009/

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