2011-01-28 12 views
9

Data la classe di tipoTipo problema riguardante classe "FlexibleInstances"

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

non posso scrivere

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 

a causa della

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

... che io non lo faccio capire abbastanza. Qualcosa di simile a questo funziona:

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) 

C'è un modo migliore? O dovrei usare la direttiva del compilatore suggerita?

risposta

13

Il motivo è semplice. Haskell 98 consente solo istanze per tipi "insaturi", questo è tipi che non sono corretti nelle loro variabili di tipo. Leggi il messaggio di errore che fornisce con attenzione, descrive esattamente cosa vuole avere il compilatore.

Per fare quello che vuoi, ci sono fondamentalmente due modo in cui già provato:

  • Accendere FlexibleInstances. Questo è il modo più comune, in quanto questa estensione è una delle più utilizzate.
  • Avvolgere in un newtype. Dà compatibilità ma è brutto.

Scegliere una;)

6

È possibile utilizzare il pragma del modulo {-# LANGUAGE FlexibleInstances #-} anziché la direttiva del compilatore. L'ambito di questo pragma è limitato a un singolo modulo.

+1

Certo, ma la mia domanda era più perché ottengo questo errore a tutti, e se c'è un modo meno brutto per istanziare la mia classe di tipo nella norma Haskell. – Landei

Problemi correlati