Haskell Language Overloaded Literals Strings


The type of the literal

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.

Using string literals

{-# 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.