从来没有摆弄过这些东西,但这里可能有两个部分答案,对你来说已经足够了。恐怕这不是一个通用的解决方案,也不是一种制作Dynamic
和实例的方法Eq
(如果它很容易,它可能已经是一个)。
但是在您最后的评论中,您说您只想比较自己的类型。所以,部分答案1:
Dynamics
如果您猜出它们的类型,您当然可以比较两者。例如:
eqInt :: Int -> Int -> Bool
eqInt = (==)
x = toDyn (3::Int)
y = toDyn (3::Int)
z = toDyn (4::Int)
compareDynamic :: (Typeable a, Eq a) =>
(a -> a -> Bool) ->
Dynamic -> Dynamic -> Maybe Bool
compareDynamic eq x y = do
let dEq = toDyn eq
fn1 <- dynApply dEq x
res <- dynApply fn1 y
fromDynamic res
现在:
...> compareDynamic eqInt x y
Just True
...> compareDynamic eqInt x z
Just False
但是,尽管 的多态类型具有误导性,但compareDynamic
您只能传入单态比较函数。看:
...> compareDynamic (==) x z
Nothing
我想这是因为类型系统无法知道(==)
它应该在此处实际使用哪个实例。我保持compareDynamic
多态,所以你不必为每种类型创建单独的函数。
现在,由于您只想比较自己的类型,您可以只列出一个按顺序尝试的比较函数列表:
eqs = [eqMyTypeA, eqMyTypeB, eqMyTypeC]
comp dynA dynB = catMaybes $ map (\eq -> eq dynA dynB) eqs
并且[]
将表示两种不同的类型,[Just False]
具有不同值[Just True]
的相同类型以及相同的类型和值。
如果您有大量类型,您也可以在进行任何比较之前确定构造函数,(这是部分答案2)并根据它选择正确的函数。如果构造函数不同,您根本不必尝试比较:
constructor :: Dynamic -> TyCon
constructor = typeRepTyCon . dynTypeRep
并有一个将构造函数与相等函数匹配的查找表。
结束语:如果需要,请三思。如果需要Dynamic
,请三思而后行,大多数 Haskell 程序都不需要。不只是 Java 思想潜入吗?