2016-10-05 34 views

回答

2

由于使用标准EqOrd的比较类型类要求被比较的两个值具有完全相同的类型(包括幻像类型参数),因此需要定义自己的比较运算符或使用存在性包装。例如:

{-# LANGUAGE ExistentialQuantification #-} 

newtype MyType a = MyType { getInt :: Int } 

data SomeType = forall a . SomeType (MyType a) 

instance Eq SomeType where 
    (SomeType (MyType a)) == (SomeType (MyType b)) = a == b 

instance Ord SomeType where 
    compare (SomeType (MyType a)) (SomeType (MyType b)) = compare a b 

test = SomeType a < SomeType b where 
    a :: MyType Char 
    a = MyType 10 

    b :: MyType Float 
    b = MyType 15 

另一种选择是使用Data.Coerce,它允许您使用标准的比较功能,而无需编写任何样板实例。您只需提供一些明确的类型签名:

import Data.Coerce 

test2 :: Bool 
test2 = coerce ((<) :: Int -> Int -> Bool) a b where 
    a :: MyType Char 
    a = MyType 10 

    b :: MyType Float 
    b = MyType 15 
+0

上,谢谢! – user2466068

+0

其实,这并不能解答原来的问题。最初的目标是首先通过类型'a'和'b'比较'x :: MyType a'和'y :: MyType b',然后再通过值'getInt x'和'getInt y'进行比较。您只是通过不同类型的对象的值进行比较。但是你的比较在类型方面不是字典。 – Shersh