Given the type class
class Dictionary w where
insert :: String -> String -> w -> w
remove :: String -> w -> w
lookUp :: String -> w -> String
I can't write
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
because of
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)]'
... which I don't quite understand. Something like this works:
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)
Is there a better way? Or should I use the suggested compiler directive?
The reason is simple. Haskell 98 only allows instances for "unsaturated" types, this is types that are not fixed in their type variables. Read the error message it gives carefully, it exactly describes what the compiler wants to have.
To do what you want, there are basically the two way you already tried:
Choose one ;)
You can use pragma of form {-# LANGUAGE FlexibleInstances #-}
instead of compiler directive. Scope of such pragma is limited to a single module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With