2011-01-28 54 views
9

給定類型的類Type類問題

class Dictionary w where 
    insert :: String -> String -> w -> w 
    remove :: String -> w -> w 
    lookUp :: String -> w -> String 

我不能寫,因爲

Illegal instance declaration for `Dictionary[(String, String)]' 
    (All instance types must be of the form (T a1 ... an) 
    where a1 ... an are type *variables*, 
    and each type variable appears at most once in the instance head. 
    Use -XFlexibleInstances if you want to disable this.) 
In the instance declaration for `Dictionary[(String, String)]' 

...我不

instance Dictionary [(String,String)] where 
    insert key value dic = (key,value) : remove key dic 
    remove key dic = filter (\entry -> (fst entry) /= key) dic 
    lookUp key [] = "not found" 
    lookUp key ((k,v):xs) | k == key = v 
         | otherwise = lookUp key xs 

很明白。像這樣的作品:

newtype Dic = Dic [(String,String)] 

instance Dictionary Dic where 
    insert key value (Dic dic) = Dic $ (key,value) : filter (\entry -> (fst entry) /= key) dic 
    remove key (Dic dic) = Dic $ filter (\entry -> (fst entry) /= key) dic 
    lookUp key (Dic []) = "not found" 
    lookUp key (Dic ((k,v):xs)) | k == key = v 
           | otherwise = lookUp key (Dic xs) 

有沒有更好的方法?或者我應該使用建議的編譯器指令?

回答

13

原因很簡單。 Haskell 98只允許「不飽和」類型的實例,這是在它們的類型變量中沒有固定的類型。仔細閱讀它給出的錯誤信息,它確切地描述了編譯器想要的東西。

做你想做什麼,有基本上你已經嘗試過了兩路:

  • 接通FlexibleInstances。這是最常用的方式,因爲這種擴展是最常用的方式之一。
  • 將它包裝成新類型。提供兼容性,但很醜。

選擇一個;)當然

6

您可以使用形式{-# LANGUAGE FlexibleInstances #-}的編譯指示代替編譯器指令。這種編譯指示的範圍限於單個模塊。

+1

,但我的問題是,爲什麼更多的我得到這個錯誤在所有,如果有一個不太難看的方式來實例化標準哈斯克爾我喜歡的類型類。 – Landei 2011-01-28 10:03:31