For convenience, Hakaru offers functions to convert between the four different numeric types in the language. These types are

Amongst these types there are a collection of safe and unsafe coercions. A safe coercion is one which is always guaranteed to be valid. For example, converting a nat to an int is always safe. Converting an int to a nat is unsafe as the value can negative, and lead to runtime errors.

These are represented in the AST using the CoerceTo and UnsafeFrom constructors. Note that coercions are always defined in terms of the safe direction to go to.

CoerceTo_   :: !(Coercion a b) -> SCon '[ LC a ] b
UnsafeFrom_ :: !(Coercion a b) -> SCon '[ LC b ] a

Internally, coercions are specified using the Coercion datatype. This datatype states that each coercion is made up of a series of primitive coercions.

data Coercion :: Hakaru -> Hakaru -> * where
    CNil :: Coercion a a
    CCons :: !(PrimCoercion a b) -> !(Coercion b c) -> Coercion a c

These primitive coercions can either involve loosening a restriction on the sign of the value, or changing the numeric value to be over a continuous value. For example, to coerce from int to real, we would have a single Coercion with a PrimCoercion in it with the Continuous data constructor.

data PrimCoercion :: Hakaru -> Hakaru -> * where
    Signed     :: !(HRing a)       -> PrimCoercion (NonNegative a) a
    Continuous :: !(HContinuous a) -> PrimCoercion (HIntegral   a) a