HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Moduleghc-10.0.0.20260917GHC2024

GHC.Types.Literal

Core literals

  • 4 types
  • 75 values

Main data type

4 declarations
datadata Literal
#

So-called Literals are one of:

  • An unboxed numeric literal or floating-point literal which is presumed to be surrounded by appropriate constructors (Int#, etc.), so that the overall thing makes sense.

We maintain the invariant that the Integer in the LitNumber constructor is actually in the (possibly target-dependent) range. The mkLit{Int,Word}*Wrap smart constructors ensure this by applying the target machine's wrapping semantics. Use these in situations where you know the wrapping semantics are correct.

  • The literal derived from the label mentioned in a "foreign label" declaration (LitLabel)

  • A LitRubbish to be used in place of values that are never used.

  • A character

  • A string

  • The NULL pointer

Constructors

Instances6Eq, Data, Ord, NFData, Outputable, Binary
  • Eq LiteralDefined in ghc-10.0.0.20260917 · GHC.Types.Literal
  • Data LiteralDefined in ghc-10.0.0.20260917 · GHC.Types.Literal
  • Ord LiteralDefined in ghc-10.0.0.20260917 · GHC.Types.Literal

    Needed for the Ord instance of AltCon, which in turn is needed in GHC.Data.TrieMap.CoreMap.

  • NFData LiteralDefined in ghc-10.0.0.20260917 · GHC.Types.Literal
  • Outputable LiteralDefined in ghc-10.0.0.20260917 · GHC.Types.Literal
  • Binary LiteralDefined in ghc-10.0.0.20260917 · GHC.Types.Literal
datadata LitNumType
#

Numeric literal type

Constructors

Instances6Enum, Eq, Data, Ord, NFData, Binary
datadata LitFloating
#

Represents a known Float# or Double# literal on the target machine.

Instances6Eq, Data, Ord, Show, NFData, Binary
  • Eq LitFloatingDefined in ghc-10.0.0.20260917 · GHC.Types.Literal.Floating

    This instance intentionally disagrees with the equality predicate (==) on Float or Double values: It is reflexive even on NaNs and distinguishes between positive and negative zero. Use litFloatingComparisonOp if you need to match Float or Double.

  • Data LitFloatingDefined in ghc-10.0.0.20260917 · GHC.Types.Literal.Floating
  • Ord LitFloatingDefined in ghc-10.0.0.20260917 · GHC.Types.Literal.Floating

    The ordering represented by this instance is pretty arbitrary and may change without notice. Do not rely on its behavior!

  • Show LitFloatingDefined in ghc-10.0.0.20260917 · GHC.Types.Literal.Floating
  • NFData LitFloatingDefined in ghc-10.0.0.20260917 · GHC.Types.Literal.Floating
  • Binary LitFloatingDefined in ghc-10.0.0.20260917 · GHC.Types.Literal.Floating

Creating Literals

Creates a Literal of type Int#, as well as a Boolean flag indicating overflow. That is, if the argument is out of the (target-dependent) range the argument is wrapped and the overflow flag will be set. See Note [WordInt underflowoverflow]

Creates a Literal of type Word#, as well as a Boolean flag indicating carry. That is, if the argument is out of the (target-dependent) range the argument is wrapped and the carry flag will be set. See Note [WordInt underflowoverflow]

valuemkLitString :: String -> Literal
#

Creates a Literal of type Addr#, which is appropriate for passing to e.g. some of the "error" functions in GHC.Err such as GHC.Err.runtimeError

Operations on Literals

Predicates on Literals and their contents

valuelitIsTrivial :: Literal -> Bool
#

True if there is absolutely no penalty to duplicating the literal. False principally of strings.

"Why?", you say? I'm glad you asked. Well, for one duplicating strings would blow up code sizes. Not only this, it's also unsafe.

Consider a program that wants to traverse a string. One way it might do this is to first compute the Addr# pointing to the end of the string, and then, starting from the beginning, bump a pointer using eqAddr# to determine the end. For instance,

-- Given pointers to the start and end of a string, count how many zeros
-- the string contains.
countZeros :: Addr# -> Addr# -> -> Int
countZeros start end = go start 0
  where
    go off n
      | off addrEq# end = n
      | otherwise         = go (off plusAddr# 1) n'
      where n' | isTrue# (indexInt8OffAddr# off 0# ==# 0#) = n + 1
               | otherwise                                 = n

Consider what happens if we considered strings to be trivial (and therefore duplicable) and emitted a call like countZeros "hello"# ("hello"# plusAddr# 5). The beginning and end pointers do not belong to the same string, meaning that an iteration like the above would blow up terribly. This is what happened in #12757.

Ultimately the solution here is to make primitive strings a bit more structured, ensuring that the compiler can't inline in ways that will break user code. One approach to this is described in #8472.

valueisZeroLit :: Literal -> Bool
#

Tests whether the literal represents a zero of whatever type it is. For floating-point literals, positive and negative zero both return True.

valueisOneLit :: Literal -> Bool
#

Tests whether the literal represents a one of whatever type it is

valuemapLitValue :: Platform -> (Integer -> Integer) -> Literal -> Literal
#

Apply a function to the Integer contained in the Literal, for when that makes sense, e.g. for Char and numbers. For fixed-size integral literals, the result will be wrapped in accordance with the semantics of the target type. See Note [WordInt underflowoverflow]

Coercions