2016-09-21 105 views
0

我有一個看起來像這樣的類型,我想compare函數只考慮整數的大小。Haskell實例Ord困難

data Cell = FromLeft Coordinate Int 
      | FromTop Coordinate Int 
      | FromDiagonal Coordinate Int 
      | Empty Coordinate 
    deriving (Eq, Read, Show) 

下面的代碼工作,但我寧願東西更優雅

instance Ord Cell where 
    compare (FromLeft _ x) (FromLeft _ y) = compare x y 
    compare (FromRight _ x) (FromLeft _ y) = compare x y 
    [...] 
+0

這不是一個好的Ord實例,因爲即使它們在「座標」字段中不同,它們的比較值也是相等的。另外,'Empty'應該如何比較? – leftaroundabout

+0

@leftroundabout是的,你讓我意識到'''Ord'''真的不是我所追求的。就像在Haskell中一樣,你花費了大量時間來解決類型系統問題,只是意識到你應該一直在傾聽它。 – davorb

+0

您可能會考慮爲您的Ord實例定義一個新類型,而不是直接在Cell中定義它(就像沒有用於任何數值類型的Monoid實例,而是用於Product和Sum的單獨實例一樣)類型)。 – chepner

回答

4

你可以定義一個輔助功能:

extractInt :: Cell -> Int 
extractInt (FromLeft _ x) = x 
extractInt (FromTop _ x) = x 
extractInt (FromDiagonal _ x) = x 
extractInt Empty = ??? 

然後

instance Ord Cell where 
    compare c1 c2 = compare (extractInt c1) (extractInt c2) 

但是要小心:上面的實例違反反對稱定律,如果x<=yy<=x然後x==y。所以它並不是真的定義一個訂單而是一個預訂。