Overloaded Literals
Strings
Section titled “Strings”The type of the literal
Section titled “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 -XOverloadedStringsPrelude> :t "foo""foo" :: Data.String.IsString t => tThis 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
Section titled “Using string literals”{-# LANGUAGE OverloadedStrings #-}
import Data.Text (Text, pack)import Data.ByteString (ByteString, pack)
withString :: StringwithString = "Hello String"
-- The following two examples are only allowed with OverloadedStrings
withText :: TextwithText = "Hello Text" -- instead of: withText = Data.Text.pack "Hello Text"
withBS :: ByteStringwithBS = "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.
Floating Numeral
Section titled “Floating Numeral”The type of the literal
Section titled “The type of the literal”Prelude> :t 1.01.0 :: Fractional a => aChoosing a concrete type with annotations
Section titled “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 :: Double1.0it :: DoublePrelude> 1.0 :: Data.Ratio.Ratio Int1 % 1it :: GHC.Real.Ratio Intif 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 :: IntInteger Numeral
Section titled “Integer Numeral”The type of the literal
Section titled “The type of the literal”Prelude> :t 11 :: Num a => achoosing a concrete type with annotations
Section titled “choosing a concrete type with annotations”You can specify the type as long as the target type is Num with an annotation:
Prelude> 1 :: Int1it :: IntPrelude> 1 :: Double1.0it :: DoublePrelude> 1 :: Word1it :: Wordif 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 :: StringList Literals
Section titled “List Literals”GHC’s OverloadedLists extension allows you to construct list-like data structures with the list literal syntax.
This allows you to Data.Map like this:
> :set -XOverloadedLists> import qualified Data.Map as M> M.lookup "foo" [("foo", 1), ("bar", 2)]Just 1Instead of this (note the use of the extra M.fromList):
> import Data.Map as M> M.lookup "foo" (M.fromList [("foo", 1), ("bar", 2)])Just 1Remarks
Section titled “Remarks”Integer Literals
Section titled “Integer Literals”is a numeral without a decimal point
for example 0, 1, 42, …
is implicitly applied to fromInteger which is part of the Num type class so it indeed has type Num a => a - that is it can have any type that is an instance of Num
Fractional Literals
Section titled “Fractional Literals”is a numeral with a decimal point
for example 0.0, -0.1111, …
is implicitly applied to fromRational which is part of the Fractional type class so it indeed has type a => a - that is it can have any type that is an instance of Fractional
String Literals
Section titled “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 from the Data.String.IsString type class
This is often used to replace String with Text or ByteString.
List Literals
Section titled “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 extension.
By default, the type of [] is:
> :t [][] :: [t]With OverloadedLists, this becomes:
[] :: GHC.Exts.IsList l => l