HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleint-cast-0.2.0.0Haskell2010

Data.IntCast

This module provides for statically or dynamically checked conversions between Integral types.

  • 4 types
  • 4 values
  • Packageint-cast-0.2.0.0
  • Exports12
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceIntCast.hs

Conversion functions

0 declarations

statically checked

In the table below each cell denotes which of the three intCast, intCastIso and intCastEq conversion operations are allowed (i.e. by the type-checker). The rows represent the domain a while the columns represent the codomain b of the a->b-typed conversion functions.

Note: The table above assumes a 64-bit platform (i.e. where finiteBitSize (0 :: Word) == 64).

dynamically checked

valueintCastMaybe :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
#

Run-time-checked integer conversion

This is an optimized version of the following generic code below

intCastMaybeRef :: (Integral a, Integral b) => a -> Maybe b
intCastMaybeRef x
  | toInteger x == toInteger y = Just y
  | otherwise                  = Nothing
  where
    y = fromIntegral x

The code above is rather inefficient as it needs to go via the Integer type. The function intCastMaybe, however, is marked INLINEABLE and if both integral types are statically known, GHC will be able optimize the code signficantly (for -O1 and better).

For instance (as of GHC 7.8.1) the following definitions

w16_to_i32 = intCastMaybe :: Word16 -> Maybe Int32

i16_to_w16 = intCastMaybe :: Int16 -> Maybe Word16

are translated into the following (simplified) GHC Core language

w16_to_i32 = \x -> Just (case x of _ { W16# x# -> I32# (word2Int# x#) })

i16_to_w16 = \x -> case eta of _
  { I16# b1 -> case tagToEnum# (<=# 0 b1) of _
      { False -> Nothing
      ; True -> Just (W16# (narrow16Word# (int2Word# b1)))
      }
  }

Note: Starting with base-4.8, this function has been added to Data.Bits under the name toIntegralSized.

Registering new integer types

2 declarations
familytype family IntBaseType a :: IntBaseTypeK
#

The (open) type family IntBaseType encodes type-level information about the value range of an integral type.

This module also provides type family instances for the standard Haskell 2010 integral types (including Foreign.C.Types) as well as the Natural type.

Here's a simple example for registering a custom type with the Data.IntCast facilities:

-- user-implemented unsigned 4-bit integer
data Nibble = …

-- declare meta-information
type instance IntBaseType Nibble = FixedWordTag 4

-- user-implemented signed 7-bit integer
data MyInt7 = …

-- declare meta-information
type instance IntBaseType MyInt7 = FixedIntTag 7

The type-level predicate IsIntSubType provides a partial ordering based on the types above. See also intCast.

Instances30IntBaseType, …
datadata IntBaseTypeK
#

(Kind) Meta-information about integral types.

If also a Bits instance is defined, the type-level information provided by IntBaseType ought to match the meta-information that is conveyed by the Bits class' isSigned and bitSizeMaybe methods.

Constructors

  • FixedIntTag Nat

    fixed-width n-bit integers with value range \left[ -2^{n-1}, 2^{n-1}-1 \right] .

  • FixedWordTag Nat

    fixed-width n-bit integers with value range \left[ 0, 2^{n} \right] .

  • BigIntTag

    integers with value range \left] -\infty, +\infty \right[ .

  • BigWordTag

    naturals with value range \left[ 0, +\infty \right[ .

Type-level predicates

6 declarations

The following type-level predicates are used by intCast, intCastIso, and intCastEq respectively.

familytype family IsIntBaseSubType (a :: IntBaseTypeK) (b :: IntBaseTypeK) :: Bool where
#

Closed type family providing the partial order of (improper) subtype-relations

IsIntSubType provides a more convenient entry point.

familytype family IsIntBaseTypeIso (a :: IntBaseTypeK) (b :: IntBaseTypeK) :: Bool where
#

Closed type family representing an equality-relation on bit-width

This is a superset of the IsIntBaseTypeEq relation, as it ignores the signedness of fixed-size integers (i.e. Int32 is considered equal to Word32).

IsIntTypeIso provides a more convenient entry point.