Haskell:在类型类之间转换

Haskell:在类型类之间转换,haskell,Haskell,对于此数据: data A = A data B = B class C1 a where repr :: a -> String instance C1 A where repr _ = "A" instance C1 B where repr _ = "B" class C2 a instance C2 A 有没有一种方法可以实现这种类型的功能 conv :: (C1 a, C2 b) => a -> Maybe b 它应该返回Just。id用于作为C2实例的类型的

对于此数据:

data A = A
data B = B

class C1 a where repr :: a -> String
instance C1 A where repr _ = "A"
instance C1 B where repr _ = "B"

class C2 a
instance C2 A
有没有一种方法可以实现这种类型的功能

conv :: (C1 a, C2 b) => a -> Maybe b
它应该返回
Just。id
用于作为
C2
实例的类型的参数,而
Nothing
用于任何其他类型


repr
是内射的。我可以更改class
C2
,但是class
C1
在外部库中。

为什么需要
C2
类型类?您可以简单地执行以下操作:

conv::c1a=>a->可能是a
conv a=案例报告a
“A”->只是一个
_->没有
这是在假定
repr
函数为空的情况下工作的


编辑:以下是如何以您想要的方式实现
conv
功能:

{-#语言类型族}
conv::(c1a,c2b,a~b)=>a->Maybe b
conv a=案例报告a
“A”->只是一个
_->没有

请注意,等式约束
a~b
是必需的。它告诉编译器类型
a
和类型
b
必须是相同的类型。要使用相等约束,我们需要启用
TypeFamilies
扩展。

为什么需要
C2
类型类?您可以简单地执行以下操作:

conv::c1a=>a->可能是a
conv a=案例报告a
“A”->只是一个
_->没有
这是在假定
repr
函数为空的情况下工作的


编辑:以下是如何以您想要的方式实现
conv
功能:

{-#语言类型族}
conv::(c1a,c2b,a~b)=>a->Maybe b
conv a=案例报告a
“A”->只是一个
_->没有


请注意,等式约束
a~b
是必需的。它告诉编译器类型
a
和类型
b
必须是相同的类型。要使用相等约束,我们需要启用
TypeFamilies
扩展。

否,这是不可能的。开放世界假设说,没有办法显示(无论是在编译时还是在运行时)给定类型不是给定类的实例。

不,这是不可能的。开放世界假设认为(无论是在编译时还是在运行时)没有办法表明给定类型不是给定类的实例。

有许多
C2
(数百个)的实例,
C2
类实际上有几个方法。使用这个解决方案(根本没有类),我们必须创建几个不同的大函数,类似于
conv
,每个函数基本上都会列出
C2
实例的所有类型名称。此外,我们希望确保,对于作为
C2
实例的每种类型,都实现了所有方法。同样,使用单独的函数会很困难……为什么需要创建几个类似于
conv
的函数?如果有数百个
C2
实例,那么它将是一个相当大的函数。确保实现类型类实例的所有方法是编译器的工作。你的问题太简单了。我不知道你想干什么。请具体一点。这似乎是一个问题。对于这些问题,还有重叠的实例和类型族解决方法。@SergeyMitskevich,你想让我花30多分钟来构建和解释一个技术示例,该技术可能适合你的应用程序,也可能不适合你的应用程序?我怀疑这是对我时间的最好利用。您能正确地解释您的潜在问题吗?
C2
(数百个)的实例很多,
C2
类实际上有几种方法。使用这个解决方案(根本没有类),我们必须创建几个不同的大函数,类似于
conv
,每个函数基本上都会列出
C2
实例的所有类型名称。此外,我们希望确保,对于作为
C2
实例的每种类型,都实现了所有方法。同样,使用单独的函数会很困难……为什么需要创建几个类似于
conv
的函数?如果有数百个
C2
实例,那么它将是一个相当大的函数。确保实现类型类实例的所有方法是编译器的工作。你的问题太简单了。我不知道你想干什么。请具体一点。这似乎是一个问题。对于这些问题,还有重叠的实例和类型族解决方法。@SergeyMitskevich,你想让我花30多分钟来构建和解释一个技术示例,该技术可能适合你的应用程序,也可能不适合你的应用程序?我怀疑这是对我时间的最好利用。请你适当地解释一下你潜在的问题好吗?请更具体一些。不要把问题过于简单化。就目前而言,这个问题似乎是一个例子。你的问题的问题是,你问的是你试图解决的问题,而不是你的实际问题。您有一个需要解决的问题,并且您已经想到了一个解决方案(在您的例子中,实现了
conv
函数)。因此,您询问是否可以实现
conv
函数。但是,如果您告诉我们您的实际问题(您正试图通过实现
conv
函数来解决的问题),那么我们可以给您一个更好的答案。因此,这是对实际问题的过度简化。我也不清楚。IIRC,Haskell的设计是为了添加实例永远不会改变已经在工作的代码的行为。特别是,这意味着添加
实例c2b
不会改变
show(conv B)
@immibis、重叠和非相干ins的结果