2011-01-28 9 views
9

Teniendo en cuenta la clase de tipoTipo referente a "FlexibleInstances"

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

no puedo escribir

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 

debido

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)]' 

... que no lo hago entiendo muy bien. Algo como esto funciona:

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) 

¿Hay una manera mejor? ¿O debería usar la directiva del compilador sugerida?

Respuesta

13

La razón es simple. Haskell 98 solo permite instancias para tipos "insaturados", esto es tipos que no están fijos en sus variables de tipo. Lea el mensaje de error que proporciona cuidadosamente, describe exactamente lo que el compilador quiere tener.

Para hacer lo que quiera, hay básicamente de dos vías que ya ha probado:

  • Encienda FlexibleInstances. Esta es la forma más común, ya que esta extensión es una de las más utilizadas.
  • Envuélvalo en un newtype. Da compatibilidad pero es feo.

Escoja uno;)

6

Puede usar pragma del formulario {-# LANGUAGE FlexibleInstances #-} en lugar de la directiva del compilador. El alcance de tal pragma está limitado a un solo módulo.

+1

Claro, pero mi pregunta era más de por qué me sale este error en absoluto, y si hay una manera menos feo para crear instancias de mi clase de tipo estándar en Haskell. – Landei

Cuestiones relacionadas