Without any extensions, the type of a string literal – i.e., something between double quotes – is just a string, aka list of characters:
Prelude> :t "foo"
"foo" :: [Char]
However, when the OverloadedStrings
extension is enabled, string literals become polymorphic, similar to number literals:
Prelude> :set -XOverloadedStrings
Prelude> :t "foo"
"foo" :: Data.String.IsString t => t
This allows us to define values of string-like types without the need for any explicit conversions. In essence, the OverloadedStrings
extension just wraps every string literal in the generic fromString
conversion function, so if the context demands e.g. the more efficient Text
instead of String
, you don't need to worry about that yourself.
{-# LANGUAGE OverloadedStrings #-}
import Data.Text (Text, pack)
import Data.ByteString (ByteString, pack)
withString :: String
withString = "Hello String"
-- The following two examples are only allowed with OverloadedStrings
withText :: Text
withText = "Hello Text" -- instead of: withText = Data.Text.pack "Hello Text"
withBS :: ByteString
withBS = "Hello ByteString" -- instead of: withBS = Data.ByteString.pack "Hello ByteString"
Notice how we were able to construct values of Text
and ByteString
in the same way we construct ordinary String
(or [Char]
) Values, rather than using each types pack
function to encode the string explicitly.
For more information on the OverloadedStrings
language extension, see the extension documentation.