对于这些数据:
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对于作为C2实例的类型的参数,它应该返回Nothing,对于任何其他类型,它应该返回Nothing。
repr是内射的。我可以更改类C2,但是类C1在外部库中。
发布于 2016-03-16 05:14:09
不,这不可能。开放世界假设说,无法(无论是在编译时还是在运行时)显示给定类型不是给定类的实例。
发布于 2016-03-16 02:28:09
为什么要使用C2类型类呢?您可以简单地这样做:
conv :: C1 a => a -> Maybe a
conv a = case repr a of
"A" -> Just a
_ -> Nothing这是在假设repr函数是内射的情况下工作的。
编辑:这里介绍了如何以您想要的方式实现conv函数:
{-# LANGUAGE TypeFamilies #-}
conv :: (C1 a, C2 b, a ~ b) => a -> Maybe b
conv a = case repr a of
"A" -> Just a
_ -> Nothing注意,等式约束a ~ b是必需的。它告诉编译器,类型a和类型b必须是相同的类型。要使用相等约束,我们需要启用TypeFamilies扩展。
https://stackoverflow.com/questions/36025660
复制相似问题