Given:
data Foo = FooString String … class Fooable a where --(is this a good way to name this?) toFoo :: a -> Foo I want to make String an instance of Fooable:
instance Fooable String where toFoo = FooString GHC then complains:
Illegal instance declaration for `Fooable String' (All instance types must be of the form (T t1 ... tn) where T is not a synonym. Use -XTypeSynonymInstances if you want to disable this.) In the instance declaration for `Fooable String' If instead I use [Char]:
instance Fooable [Char] where toFoo = FooString GHC complains:
Illegal instance declaration for `Fooable [Char]' (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 `Fooable [Char]' Question:
This is because String is just a type alias for [Char], which is just the application of the type constructor [] on the type Char, so this would be of the form ([] Char). which is not of the form (T a1 .. an) because Char is not a type variable.
The reason for this restriction is to prevent overlapping instances. For example, let's say you had an instance Fooable [Char], and then someone later came along and defined an instance Fooable [a]. Now the compiler won't be able to figure out which one you wanted to use, and will give you an error.
By using -XFlexibleInstances, you're basically promising to the compiler that you won't define any such instances.
Depending on what you're trying to accomplish, it might be better to define a wrapper:
newtype Wrapper = Wrapper String instance Fooable Wrapper where ...
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