2010-06-17 106 views
1

我有一些代碼,我想用一個邊緣追加到節點的數據結構:哈斯克爾奧德實例與集

import Data.Set (Set) 
import qualified Data.Set as Set 

data Node = Vertex String (Set Node) 
    deriving Show 

addEdge :: Node -> Node -> Node 
addEdge (Vertex name neighbors) destination 
    | Set.null neighbors = Vertex name (Set.singleton destination) 
    | otherwise    = Vertex name (Set.insert destination neighbors) 

然而,當我嘗試編譯我得到這個錯誤:

No instance for (Ord Node) 
     arising from a use of `Set.insert' 

據我所知,Set.insert只需要一個值和一個集合來插入它。什麼是Ord?

回答

6

在GHCI:

> import Data.Set 
> :t insert 
insert :: (Ord a) => a -> Set a -> Set a 

所以,是的,但是我還是希望Ord。至於Ord是什麼意思,它是型號對於有序值。在這種情況下,它是必需的,因爲Data.Set使用搜索樹,因此需要能夠比較值以查看哪個更大或者它們是否相等。

幾乎所有標準的內置數據類型的Ord實例,以及像列表,元組,Maybe等作爲實例Ord的事情時,他們的類型參數(S)的。當然,最顯着的例外是函數,其中沒有明確的排序(甚至相等)概念可以定義。

在很多情況下,你可以自動使用deriving條款的聲明之後自己的數據類型創建類型的類的實例:

data Foo a = Foo a a Int deriving (Eq, Ord, Show, Read) 

參數化類型,自動推導依賴於類型參數也被一個實例,就像列表,元組等一樣。

此外Ord,一些重要的類型類是Eq(相等比較,但不能小於/大於),Enum(類型,您可以枚舉值,如計算Integer S),和Read/Show(簡單的序列化/反序列化與字符串)。要了解有關類型類別的更多信息,請嘗試this chapter in Real World Haskell,或者,有關更一般的概述,請參閱a Wikipedia article

4

Haskell集合基於搜索樹。爲了在搜索樹中放置一個元素,必須給出元素的排序順序。

data Node = Vertex String (Set Node) 
    deriving (Show, Eq, Ord) 

您可以通過Data.Set.insert

(Ord a) => a -> Set a -> Set a 

的簽名,見條例的要求:你可以將它添加到您的數據申報,即獲得奧德就像你獲得展會部分(Ord a) =>建立了一個約束,即存在a的類型Ord的實例。 haskell tutorial中的section on type classes給出了更全面的解釋。

+0

派生語句必須加括號,但是,這似乎工作。謝謝。 – 2010-06-17 20:49:07