Cannot make String an instance of a class in Haskell

I play trying to understand classes in Haskell. I wrote some dumb lines of code to understand it. I wrote a class called Slang , which has one function. When I make Integer an instance of my class, it works fine. But when I make String an instance of my class, it will not compile. I was looking for a program based on what says error, but to no avail. I have an idea why it works ...

Here is the code followed by the error:

 module Practice where class Slang s where slangify :: s -> String instance Slang Integer where slangify int = "yo" instance Slang String where -- When I take this segment out, it works fine slangify str = "bro" 

ERROR:

 Prelude> :load Practice [1 of 1] Compiling Practice ( Practice.hs, interpreted ) Practice.hs:9:10: Illegal instance declaration for `Slang 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 `Slang String' Failed, modules loaded: none. Prelude> 
+8
class haskell
source share
2 answers

The problem is that String is not a base type of type Integer. What you are trying to do is actually

 instance Slang [Char] where slangify str = "bro" 

However, Haskell98 prohibits this type of type class in order to simplify the task and make it harder for people to write overlapping instances such as

 instance Slang [a] where -- Strings would also fit this definition. slangify list = "some list" 

In any case, as the error message indicates, you can get around this limitation by enabling the FlexibleInstances extension.

+12
source share

I did some research in my Haskell literature (other than in my current Bible) and found an example that effectively solves my problem.

Basically, in this workaround, you set Char as an instance of the class (in the example book it is called Visible ), and then you can set [chars] aka String to be an instance of the class ONLY with the condition that the variable of type chars is an instance of `Visible '. This is easier to understand if you look at the code below:

 module Practice where class Visible a where toString :: a -> String size :: a -> Int instance Visible Char where toString ch = [ch] size _ = 1 instance Visible a => Visible [a] where toString = concat . map toString size = foldr (+) 1 . map size 

My download call and GHCi function:

 *Practice> :l Practice [1 of 1] Compiling Practice ( Practice.hs, interpreted ) Ok, modules loaded: Practice. *Practice> size "I love Stack!" 14 *Practice> 

Eureka!

+5
source share

All Articles