Normally, string literals in Haskell have a type of String (which is a type alias for [Char]). While this isn't a problem for smaller, educational programs, real-world applications often require more efficient storage such as Text or ByteString.
OverloadedStrings simply changes the type of literals to
"test" :: Data.String.IsString a => a
Allowing them to be directly passed to functions expecting such a type. Many libraries implement this interface for their string-like types including Data.Text and Data.ByteString which both provide certain time and space advantages over [Char].
There are also some unique uses of OverloadedStrings like those from the Postgresql-simple library which allows SQL queries to be written in double quotes like a normal string, but provides protections against improper concatenation, a notorious source of SQL injection attacks.
To create a instance of the IsString class you need to impliment the fromString function. Example†:
data Foo = A | B | Other String deriving Show
instance IsString Foo where
fromString "A" = A
fromString "B" = B
fromString xs = Other xs
tests :: [ Foo ]
tests = [ "A", "B", "Testing" ]
† This example courtesy of Lyndon Maydwell (sordina on GitHub) found here.