# 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 (opens new window):

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 (opens new window) conversion function, so if the context demands e.g. the more efficient Text (opens new window) 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 (opens new window).

# Floating Numeral

# The type of the literal

Prelude> :t 1.0
1.0 :: Fractional a => a

# Choosing a concrete type with annotations

You can specify the type with a type annotation. The only requirement is that the type must have a Fractional instance.

Prelude> 1.0 :: Double
1.0
it :: Double
Prelude> 1.0 :: Data.Ratio.Ratio Int
1 % 1
it :: GHC.Real.Ratio Int 

if not the compiler will complain

Prelude> 1.0 :: Int
<interactive>:
    No instance for (Fractional Int) arising from the literal `1.0'
    In the expression: 1.0 :: Int
    In an equation for `it': it = 1.0 :: Int

# Integer Numeral

# The type of the literal

Prelude> :t 1
1 :: Num a => a

# choosing a concrete type with annotations

You can specify the type as long as the target type is Num with an annotation:

Prelude> 1 :: Int
1
it :: Int
Prelude> 1 :: Double
1.0
it :: Double
Prelude> 1 :: Word
1
it :: Word

if not the compiler will complain

Prelude> 1 :: String

<interactive>:
    No instance for (Num String) arising from the literal `1'
    In the expression: 1 :: String
    In an equation for `it': it = 1 :: String

# List Literals

GHC's OverloadedLists (opens new window) extension allows you to construct list-like data structures with the list literal syntax.

This allows you to Data.Map (opens new window) like this:

> :set -XOverloadedLists
> import qualified Data.Map as M
> M.lookup "foo" [("foo", 1), ("bar", 2)]
Just 1

Instead of this (note the use of the extra M.fromList (opens new window)):

> import Data.Map as M
> M.lookup "foo" (M.fromList [("foo", 1), ("bar", 2)])
Just 1

# Remarks

# Integer Literals

is a numeral without a decimal point

for example 0, 1, 42, ...

is implicitly applied to fromInteger (opens new window) which is part of the Num type class (opens new window) so it indeed has type Num a => a - that is it can have any type that is an instance of Num

# Fractional Literals

is a numeral with a decimal point

for example 0.0, -0.1111, ...

is implicitly applied to fromRational (opens new window) which is part of the Fractional type class (opens new window) so it indeed has type a => a - that is it can have any type that is an instance of Fractional

# String Literals

If you add the language extension OverloadedStrings to GHC you can have the same for String-literals which then are applied to fromString (opens new window) from the Data.String.IsString type class (opens new window)

This is often used to replace String with Text or ByteString.

# List Literals

Lists can defined with the [1, 2, 3] literal syntax. In GHC 7.8 and beyond, this can also be used to define other list-like structures with the OverloadedLists (opens new window) extension.

By default, the type of [] is:

> :t []
[] :: [t]

With OverloadedLists, this becomes:

[] :: GHC.Exts.IsList l => l