2012-07-16 70 views
8

新手在這裏共同奮鬥。Haskell:我如何定義集合的類型類?

我想爲集定義一個類型類。對於這種情況,它只需要「存在」的定義。 '存在'將在一個設置項上設置一個集合和一個函數,並且返回一個布爾型的 。我如何在Haskell中定義?

即使在正確的方向下面是以下內容?因此,有類型的類定義和實現 一套具有名單,爲此,「存在」返回現在真正..

-- Set.hs -- 

class Set a b where 

    exists :: a -> (b -> Bool) -> Bool 


-- ListSet.hs -- 

instance Set ListSet a where 

    exists a f = True 

-

(結果:類參數太多`設置')

回答

13

你可以這樣做,並有足夠的擴展。至少,你需要多參數類型的類。但是,使用它會非常煩人:您需要在整個地方指定明確的類型簽名。要解決這個問題的方法之一是引入函數依賴(使用其他擴展名):

class Set a b | a -> b where 
    exists :: a -> (b -> Bool) -> Bool 

這就是說,如果你掌握設定的類型,你知道元素的類型了。然而,有,沒有任何擴展的工作更簡單的方法:拿出你自己,如果你從來沒有

class Set f where 
    exists :: f a -> (a -> Bool) -> Bool 

這裏,類型類射程達高kinded類型,這是一個巧妙的方法和硬看過它!

+1

當然,後者要求元素類型是set類型的最後一個類型參數 - 這並不總是可行的,就像你想爲'a - > Bool'創建一個實例一樣。另一方面,相關類型的家族可以解決這個問題。 – Carl 2012-07-16 17:37:28

+2

謝謝!我有第二種方式工作!我必須承認,我不太明白那裏發生了什麼,但希望它可以向我展示... – tero 2012-07-16 17:42:15

7

丹尼爾瓦格納已經給出了你想要做的完美答案。我只想補充一點你的錯誤 - Too many parameters for class 'Set'。這意味着你沒有啓用相應的GHC擴展名 - MultiParamTypeClasses。您可以通過在源文件頂部指定特殊類型的註釋來執行此操作:

{-# LANGUAGE MultiParamTypeClasses #-} 
-- 
-- Your source code here 
-- 

然後您應該可以編譯您的代碼。

丹尼爾回答中提到的另一個Haskell特性還需要啓用某些擴展,即FunctionalDependencies(這是類型聲明中的奇怪的.. | a -> b ..事件)。您可以使用逗號,像這樣在同時打開多個功能擴展:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 

卡爾的評論提到了另一種延伸,TypeFamilies,這也可以爲你正在嘗試做的(通用類集合類型或其他的提供方式種類的集合)。你可以在這裏閱讀:http://www.haskell.org/haskellwiki/Type_families

+0

我設法做到這一點,還與功能依賴方法。但是,我還必須包含'FlexibleInstances'擴展。 – tero 2012-07-16 18:20:08