2011-01-28 15 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