Safe Haskell  SafeInferred 

Manage representation of numeric values in a module.
We use three seprate versions of each numeric type. Nat# Numeric index type. B Boxed representation type. U Unboxed representation type.
A numeric index type is the type of pure values like 23#, where pure value means the mathematical value, free from any considerations about how that might be represented at runtime in the physical machine.
The Boxed and Unboxed representation types commit to a specific runtime representation, and have implications for runtime performance and space usage of the compiled program.
The boxing transform takes an input program using just pure values and numeric index types, and refines it to a program that commits to particular representations of those values. In particular, we commit to a particular representation for function arguments and results, which makes the program adhere to a function calling convention that followon transformations to lower level languages (like Core Salt) can deal with.
This Boxing transform should do just enough to make the code wellformed with respect to runtime representation. Demanddriven optimisations like local unboxing should be done in followon transformations.
We make the following representation commitments, so that the default representation is boxed.
Literal values are wrapped into their boxed representation: 23# => convert Nat] 23#
Use unboxed versions of primitive operators: add] x y => convert Nat Nat#] (add Nat [U] [B] x) (convert Nat Nat#] y))
Case scrutinees are unwrapped when matching against literal patterns: case x of { 0# > ... } => case convert [B] [Nat > ... }
After performing this transformation the program is said to use representational types, or be in representational form.
 Note: Boxing and Partial Application
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike in Haskell, we do not allow explictly unboxed types in the source program because we don't want to deal with partial applications of functions to unboxed values. With our current setup we always have a version of each function that accepts boxed values, so we never need to do generic application involving unboxed values. Fastpath function specialisations that take unboxed parameters should be created separately, and not replace the existing slowpath, fully boxed version. Taking this approach is possible in a strict language because the boxed and unboxed values have the same semantic meaning. Boxing of values does not imply lifting of the associated semantic domain.
 data Rep
 = RepNone
  RepBoxed
  RepUnboxed
 data Config a n = Config {
 configIsValueIndexType :: Type n > Bool
 configIsBoxedType :: Type n > Bool
 configIsUnboxedType :: Type n > Bool
 configBoxedOfIndexType :: Type n > Maybe (Type n)
 configUnboxedOfIndexType :: Type n > Maybe (Type n)
 configIndexTypeOfBoxed :: Type n > Maybe (Type n)
 configIndexTypeOfUnboxed :: Type n > Maybe (Type n)
 configValueTypeOfLitName :: n > Maybe (Type n)
 configValueTypeOfPrimOpName :: n > Maybe (Type n)
 configValueTypeOfForeignName :: n > Maybe (Type n)
 configNameIsUnboxedOp :: n > Bool
 configBoxedOfValue :: a > Exp a n > Type n > Maybe (Exp a n)
 configValueOfBoxed :: a > Exp a n > Type n > Maybe (Exp a n)
 configBoxedOfUnboxed :: a > Exp a n > Type n > Maybe (Exp a n)
 configUnboxedOfBoxed :: a > Exp a n > Type n > Maybe (Exp a n)
 class Boxing c where
Documentation
Representation of the values of some type.
RepNone  Values of this type cannot be directly represented in the target language. We need to use a boxed or unboxed representation instead. 
RepBoxed  Type is represented in boxed form, and thus can instantiate polymorphic types. 
RepUnboxed  Type is represented in unboxed form, and thus cannot instantiate polymorphic types. 
Config  
