2010-03-25 32 views
3

我想把這個數據類型放入一個Haskell集,但我不想給它一個Ord的一般實例。所以我想給這個集合在y-coördinate上排序,但沒有實例Ord Vector。這可能嗎?一組無序數據類型與給定的順序

data Vector = V 
    { x :: Double 
    , y :: Double 
    } deriving (Eq) 
+0

你可以存儲座標元組'(y,x)'? – kennytm 2010-03-25 08:52:41

+0

我可以做到這一點,但那對我有什麼幫助? 其實我想在不同的功能中使用不同的順序(一次x座標,一次y座標),後來我想在更多維度上擴展它。 – Ingdas 2010-03-25 08:57:23

回答

8

Set要求您使用元素類型的默認Ord實例。

如果要使用不同的Ord例如,要做到這一點的標準方法是使用自定義的newtype包裝,然後寫,一個Ord實例:

newtype Y = Y { unY :: Vector } deriving Eq 
instance Ord Y where compare = comparing ((y . unY) &&& (x . unY)) 

但由於比較的方式是等同於二元元組的比較方式,KennyTM的解決方案在這裏最簡單。

+2

不錯。我只是在輸入完全相同的東西。 – jrockway 2010-03-25 09:41:45

+1

我可以讓它工作,但我不完全明白我在輸入什麼。所以我想我可以用(\ l - >((y.unY l),(x.unY l)))來代替&&&。但我真的不明白這是一個函數Num => b-> a(我從比較文檔中得到這個簽名) 你可以用較低級別的Haskell改寫它嗎?我在Haskell仍然是一個新手 – Ingdas 2010-03-25 11:05:26

+0

@ngdas:你在哪裏得到'Num'? '比較'的簽名是'Ord a =>(b - > a) - > b - > b - > Ordering'(http://hackage.haskell.org/packages/archive/base/latest/doc/html /Data-Ord.html#v:comparing) – kennytm 2010-03-25 11:40:36

4

您可以將矢量轉換成一個元組:

toTuple :: Vector -> (Double, Double) 
toTuple (V x y) = (y, x) 

fromTuple :: (Double, Double) -> Vector 
fromTuple (y, x) = V x y 

由於元組推導奧德(使用字典比較),它們可以被插入到設置。 (爲x主要訂購定義2個其他功能。)

0

我製作了Set數據類型的版本,該數據類型沒有Ord上下文,但需要在構造Set的任何地方傳入類型爲a -> a -> Ordering的函數。這對你的情況有用嗎?

(我不知道的版權狀態,它的大部分都未經檢驗的文件不被修改,所以我不只是把它在這裏...)

+0

你可以把它發給我嗎? ingdas(at)gmail(dot)com 這實際上正是我所需要的 – Ingdas 2010-03-26 10:04:45

+0

-1。通過發佈這樣的答案,你可以幫助OP,但你不幫助整個社區。 – jfpoilpret 2010-03-26 10:35:30

+0

好點,jfpoilpret。我將着手讓它在GitHub上處於可釋放狀態,這樣每個人都可以受益。我希望下週某個地方的ETA。 – yatima2975 2010-03-27 18:41:42