Skip to content

Array interchange

Python uses from hmath import interchange; C includes hmath_interchange.h. These adapters call the original Haskell array, binary/text/NumPy, compression, streaming and mapped-file functions. Source byte/shape/archive budgets, checksums, metadata, byte order, stride/offset semantics and errors remain unchanged.

Each successful C output owns one structured value; inputs are borrowed during the call and failure leaves output pointers untouched. InterchangeError uses status13 with its original four-way constructor and full message available through hmath_last_interchange_error. Python raises HMathError with interchange_error. Callbacks may supply the original checked Left by raising InterchangeError. Unexpected exceptions abort and are re-raised after cleanup.

ByteString results are owned Bytes objects. bytes(result) copies; result.view() borrows a read-only span retaining an independent reference. C uses hmath_bytes_data while retaining the owner. No terminator is implied. Binary/raw preserve IEEE bits; text follows the source policy and does not promise NaN payload preservation. boxed=True on scalar/list decoders retains native typed values when Python scalar conversion is undesirable.

Element-polymorphic operations select one original fixed-width instance using a scalar/Boolean prototype in C or dtype= in Python. Supported types are Bool8, signed/unsigned8/16/32/64, Float32/64 and Complex64/128. Array dtype and requested result type must match as in Haskell. Matrix/Tensor conversions preserve actual element types; they do not route FP32 through FP64. get_element returns the original parser program; run_decoder executes the original strict decoder, including trailing-byte checks. put_element returns the original Put program and put_bytes runs it.

Mapped array access is callback-scoped. A retained mapping capability rejects data reads after scope exit through the original closed-state checks; copied Bytes remain valid. File writes retain the source's IO effects and partial-write behavior. open_handle/close_handle and seek/tell/flush expose real binary Haskell handles for the original chunked APIs. Handles are shared resources; close them explicitly before releasing their owners.

big_endian

interchange.big_endian()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.BigEndian. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Endian
hmath_status hmath_interchange_value_big_endian(hmath_context *context, hmath_value **out);

bool8

interchange.bool8()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.Bool8. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_bool8(hmath_context *context, hmath_value **out);

c128

interchange.c128()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.C128. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_c128(hmath_context *context, hmath_value **out);

c64

interchange.c64()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.C64. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_c64(hmath_context *context, hmath_value **out);

c_order

interchange.c_order()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.COrder. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Order
hmath_status hmath_interchange_value_c_order(hmath_context *context, hmath_value **out);

f32

interchange.f32()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.F32. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_f32(hmath_context *context, hmath_value **out);

f64

interchange.f64()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.F64. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_f64(hmath_context *context, hmath_value **out);

f_order

interchange.f_order()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.FOrder. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Order
hmath_status hmath_interchange_value_f_order(hmath_context *context, hmath_value **out);

i16

interchange.i16()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.I16. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_i16(hmath_context *context, hmath_value **out);

i32

interchange.i32()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.I32. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_i32(hmath_context *context, hmath_value **out);

i64

interchange.i64()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.I64. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_i64(hmath_context *context, hmath_value **out);

i8

interchange.i8()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.I8. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_i8(hmath_context *context, hmath_value **out);

interchange_io_error

interchange.interchange_io_error(message)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.InterchangeIOError. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

String -> InterchangeError
hmath_status hmath_interchange_value_interchange_io_error(hmath_context *context, const hmath_value *message, hmath_value **out);

invalid_data

interchange.invalid_data(message)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.InvalidData. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

String -> InterchangeError
hmath_status hmath_interchange_value_invalid_data(hmath_context *context, const hmath_value *message, hmath_value **out);

limit_exceeded

interchange.limit_exceeded(message)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.LimitExceeded. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

String -> InterchangeError
hmath_status hmath_interchange_value_limit_exceeded(hmath_context *context, const hmath_value *message, hmath_value **out);

limits

interchange.limits(max_bytes, max_elements, max_rank, max_metadata, max_archive_entries)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.Limits. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Int -> Int -> Int -> Int -> Int -> Limits
hmath_status hmath_interchange_value_limits(hmath_context *context, const hmath_value *max_bytes, const hmath_value *max_elements, const hmath_value *max_rank, const hmath_value *max_metadata, const hmath_value *max_archive_entries, hmath_value **out);

little_endian

interchange.little_endian()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.LittleEndian. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Endian
hmath_status hmath_interchange_value_little_endian(hmath_context *context, hmath_value **out);

u16

interchange.u16()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.U16. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_u16(hmath_context *context, hmath_value **out);

u32

interchange.u32()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.U32. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_u32(hmath_context *context, hmath_value **out);

u64

interchange.u64()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.U64. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_u64(hmath_context *context, hmath_value **out);

u8

interchange.u8()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.U8. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType
hmath_status hmath_interchange_value_u8(hmath_context *context, hmath_value **out);

unsupported

interchange.unsupported(message)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.Unsupported. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

String -> InterchangeError
hmath_status hmath_interchange_value_unsupported(hmath_context *context, const hmath_value *message, hmath_value **out);

array

interchange.array(lim, dt, en, sh, st, off, bs)

Construct a bounded view. Bool8 bytes reachable through the view must be 0 or 1. Floating payloads preserve IEEE NaNs, signed zero and infinities.

Original: HMath.Interchange.Array.array. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> DType -> Endian -> [Int] -> [Int] -> Int -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_array(hmath_context *context, const hmath_value *lim, const hmath_value *dt, const hmath_value *en, const hmath_value *sh, const hmath_value *st, const hmath_value *off, const hmath_value *bs, hmath_value **out);

array_bytes

interchange.array_bytes(value)

Return immutable backing bytes, which may include padding or data not reached by the logical strided view. Use toValues or repack for logical contents.

Original: HMath.Interchange.Array.arrayBytes. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> ByteString
hmath_status hmath_interchange_value_array_bytes(hmath_context *context, const hmath_value *value, hmath_value **out);

array_d_type

interchange.array_d_type(value)

Return the fixed-width wire dtype of an Array; this is independent of Haskell host Int/Double defaults.

Original: HMath.Interchange.Array.arrayDType. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> DType
hmath_status hmath_interchange_value_array_d_type(hmath_context *context, const hmath_value *value, hmath_value **out);

array_endian

interchange.array_endian(value)

Return explicit payload byte order; single-byte dtypes are endian-independent.

Original: HMath.Interchange.Array.arrayEndian. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> Endian
hmath_status hmath_interchange_value_array_endian(hmath_context *context, const hmath_value *value, hmath_value **out);

array_metadata

interchange.array_metadata(value)

Return descriptive UTF-8-compatible key/value metadata strings in stored order; metadata is not executable.

Original: HMath.Interchange.Array.arrayMetadata. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> [(String, String)]
hmath_status hmath_interchange_value_array_metadata(hmath_context *context, const hmath_value *value, hmath_value **out);

array_offset

interchange.array_offset(value)

Return byte offset of logical origin within arrayBytes backing storage.

Original: HMath.Interchange.Array.arrayOffset. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> Int
hmath_status hmath_interchange_value_array_offset(hmath_context *context, const hmath_value *value, hmath_value **out);

array_shape

interchange.array_shape(value)

Return logical dimensions in axis order; [] is scalar and zero axes are valid.

Original: HMath.Interchange.Array.arrayShape. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> [Int]
hmath_status hmath_interchange_value_array_shape(hmath_context *context, const hmath_value *value, hmath_value **out);

array_strides

interchange.array_strides(value)

Return signed byte strides for each axis. Unlike HMath.Tensor strides, these are bytes, not elements.

Original: HMath.Interchange.Array.arrayStrides. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> [Int]
hmath_status hmath_interchange_value_array_strides(hmath_context *context, const hmath_value *value, hmath_value **out);

contiguous_array

interchange.contiguous_array(lim, dt, en, order, sh, bs)

Given limits,dtype,endian,physical order,shape,then exact packed bytes, construct a canonical byte-strided array. Require exact byte count; invalid shape/data/limits fail.

Original: HMath.Interchange.Array.contiguousArray. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> DType -> Endian -> Order -> [Int] -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_contiguous_array(hmath_context *context, const hmath_value *lim, const hmath_value *dt, const hmath_value *en, const hmath_value *order, const hmath_value *sh, const hmath_value *bs, hmath_value **out);

default_limits

interchange.default_limits()

128 MiB of bytes, 8 million samples, rank 16, 64 KiB metadata, 256 members.

Original: HMath.Interchange.Array.defaultLimits. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits
hmath_status hmath_interchange_value_default_limits(hmath_context *context, hmath_value **out);

dense_strides

interchange.dense_strides(c_order, w, sh)

Dense strides use Integer arithmetic before conversion. Call only on validated shape/byte sizes; zero axes use zero strides to avoid overflow.

Original: HMath.Interchange.Array.denseStrides. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Order -> Int -> [Int] -> [Int]
hmath_status hmath_interchange_value_dense_strides(hmath_context *context, const hmath_value *c_order, const hmath_value *w, const hmath_value *sh, hmath_value **out);

element_bytes

interchange.element_bytes(dt)

Return fixed byte width of a DType, including complex pairs (C64=8,C128=16) and Bool8=1.

Original: HMath.Interchange.Array.elementBytes. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType -> Int
hmath_status hmath_interchange_value_element_bytes(hmath_context *context, const hmath_value *dt, hmath_value **out);

element_count

interchange.element_count(value)

Return logical shape product; scalar arrays have one element and empty axes have zero.

Original: HMath.Interchange.Array.elementCount. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> Int
hmath_status hmath_interchange_value_element_count(hmath_context *context, const hmath_value *value, hmath_value **out);

element_type

interchange.element_type(*, dtype="float64")

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.elementType. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => proxy a -> DType
hmath_status hmath_interchange_value_element_type(hmath_context *context, const hmath_value *prototype, hmath_value **out);

from_matrix

interchange.from_matrix(value, value2, value3)

Given limits,endian,then typed Matrix, encode its row-major values as a rank-two Array. Dtype comes from Element; resource limits can fail.

Original: HMath.Interchange.Array.fromMatrix. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Limits -> Endian -> HMath.Matrix.Matrix a -> Either InterchangeError Array
hmath_status hmath_interchange_value_from_matrix(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, hmath_value **out);

from_tensor

interchange.from_tensor(value, value2, value3)

Given limits,endian,then typed Haskell Tensor, encode logical row-major values and preserve shape. The Element instance determines wire dtype; resource bounds can fail.

Original: HMath.Interchange.Array.fromTensor. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Limits -> Endian -> HMath.Tensor.Tensor a -> Either InterchangeError Array
hmath_status hmath_interchange_value_from_tensor(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, hmath_value **out);

from_values

interchange.from_values(limits,endian,shape,values, *, dtype="float64")

Given limits,endian,shape,then typed Element list, encode to a contiguous array with that Element dtype. Require exact shape/count match and resource bounds; failures return InterchangeError.

Original: HMath.Interchange.Array.fromValues. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Limits -> Endian -> [Int] -> [a] -> Either InterchangeError Array
hmath_status hmath_interchange_value_from_values(hmath_context *context, const hmath_value *prototype, const hmath_value *limits, const hmath_value *endian, const hmath_value *shape, const hmath_value *values, hmath_value **out);

get_element

interchange.get_element(endian, *, dtype="float64")

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.getElement. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Endian -> Data.Binary.Get.Internal.Get a
hmath_status hmath_interchange_value_get_element(hmath_context *context, const hmath_value *prototype, const hmath_value *endian, hmath_value **out);

max_archive_entries

interchange.max_archive_entries(value)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.maxArchiveEntries. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Int
hmath_status hmath_interchange_value_max_archive_entries(hmath_context *context, const hmath_value *value, hmath_value **out);

max_bytes

interchange.max_bytes(value)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.maxBytes. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Int
hmath_status hmath_interchange_value_max_bytes(hmath_context *context, const hmath_value *value, hmath_value **out);

max_elements

interchange.max_elements(value)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.maxElements. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Int
hmath_status hmath_interchange_value_max_elements(hmath_context *context, const hmath_value *value, hmath_value **out);

max_metadata

interchange.max_metadata(value)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.maxMetadata. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Int
hmath_status hmath_interchange_value_max_metadata(hmath_context *context, const hmath_value *value, hmath_value **out);

max_rank

interchange.max_rank(value)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.maxRank. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Int
hmath_status hmath_interchange_value_max_rank(hmath_context *context, const hmath_value *value, hmath_value **out);

put_element

interchange.put_element(endian,value, *, dtype="float64")

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Array.putElement. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Endian -> a -> Data.Binary.Put.Put
hmath_status hmath_interchange_value_put_element(hmath_context *context, const hmath_value *prototype, const hmath_value *endian, const hmath_value *value, hmath_value **out);

raw_decode

interchange.raw_decode(value, value2, value3, value4, value5, value6)

Given limits,dtype,endian,order,shape,then bytes, construct a packed Array. Caller supplies all metadata; exact byte-count and shape/resource validation is enforced.

Original: HMath.Interchange.Array.rawDecode. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> DType -> Endian -> Order -> [Int] -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_raw_decode(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, const hmath_value *value4, const hmath_value *value5, const hmath_value *value6, hmath_value **out);

raw_encode

interchange.raw_encode(value, value2, value3, value4)

Given limits,destination endian,physical order,then Array, repack its logical payload and return raw bytes without shape/header metadata. Checked resource/layout failures propagate.

Original: HMath.Interchange.Array.rawEncode. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Endian -> Order -> Array -> Either InterchangeError ByteString
hmath_status hmath_interchange_value_raw_encode(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, const hmath_value *value4, hmath_value **out);

repack

interchange.repack(lim, en, order, a)

Pack arbitrary views, preserving dtype and exact component bits. Complex byte swapping reverses each real/imaginary component separately.

Original: HMath.Interchange.Array.repack. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Endian -> Order -> Array -> Either InterchangeError Array
hmath_status hmath_interchange_value_repack(hmath_context *context, const hmath_value *lim, const hmath_value *en, const hmath_value *order, const hmath_value *a, hmath_value **out);

to_matrix

interchange.to_matrix(array, *, dtype=None)

Decode a matching typed rank-two Array to Matrix. Rank/dtype or checked shape conversion failures return InterchangeError.

Original: HMath.Interchange.Array.toMatrix. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Array -> Either InterchangeError (HMath.Matrix.Matrix a)
hmath_status hmath_interchange_value_to_matrix(hmath_context *context, const hmath_value *prototype, const hmath_value *array, hmath_value **out);

to_tensor

interchange.to_tensor(array, *, dtype=None)

Decode an Array of matching Element dtype to a contiguous Haskell Tensor, preserving logical shape/order. Dtype or checked tensor-construction failure returns InterchangeError.

Original: HMath.Interchange.Array.toTensor. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Array -> Either InterchangeError (HMath.Tensor.Tensor a)
hmath_status hmath_interchange_value_to_tensor(hmath_context *context, const hmath_value *prototype, const hmath_value *array, hmath_value **out);

to_values

interchange.to_values(array, *, dtype=None, boxed=False)

Decode logical row-major values as the requested Element type, requiring an exact dtype match. No silent numeric cast occurs; mismatch returns Unsupported/InvalidData.

Original: HMath.Interchange.Array.toValues. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Element a => Array -> Either InterchangeError [a]
hmath_status hmath_interchange_value_to_values(hmath_context *context, const hmath_value *prototype, const hmath_value *array, hmath_value **out);

validate_shape

interchange.validate_shape(lim, sh)

Given limits then dimensions, validate rank, nonnegative axes and element product, returning Int element count. Invalid data or exceeded limits return InterchangeError.

Original: HMath.Interchange.Array.validateShape. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> [Int] -> Either InterchangeError Int
hmath_status hmath_interchange_value_validate_shape(hmath_context *context, const hmath_value *lim, const hmath_value *sh, hmath_value **out);

with_metadata

interchange.with_metadata(value, value2, value3)

Metadata is UTF-8 in binary files; keys must be unique and nonempty. The four-byte-per-codepoint bound is intentionally conservative before encoding.

Original: HMath.Interchange.Array.withMetadata. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> [(String, String)] -> Array -> Either InterchangeError Array
hmath_status hmath_interchange_value_with_metadata(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, hmath_value **out);

crc32

interchange.crc32(value)

Standard CRC-32, compatible with ZIP and zlib, with a fixed 256-entry table.

Original: HMath.Interchange.Binary.crc32. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

ByteString -> Word32
hmath_status hmath_interchange_value_crc32(hmath_context *context, const hmath_value *value, hmath_value **out);

decode_binary

interchange.decode_binary(lim, input)

Given limits then bytes, validate HMath v1 magic/header/flags/CRC and exact framing, returning an Array. Truncation, corruption, unsupported metadata or exceeded budgets return InterchangeError.

Original: HMath.Interchange.Binary.decodeBinary. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_decode_binary(hmath_context *context, const hmath_value *lim, const hmath_value *input, hmath_value **out);

encode_binary

interchange.encode_binary(lim, a)

Given limits then Array, encode HMath wire-format v1 including shape/strides/offset/metadata/backing storage and CRC-32. Invalid metadata/layout or exceeded aggregate byte budget fails.

Original: HMath.Interchange.Binary.encodeBinary. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Array -> Either InterchangeError ByteString
hmath_status hmath_interchange_value_encode_binary(hmath_context *context, const hmath_value *lim, const hmath_value *a, hmath_value **out);

gzip

interchange.gzip()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Compression.Gzip. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Compression
hmath_status hmath_interchange_value_gzip(hmath_context *context, hmath_value **out);

raw_deflate

interchange.raw_deflate()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Compression.RawDeflate. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Compression
hmath_status hmath_interchange_value_raw_deflate(hmath_context *context, hmath_value **out);

zlib

interchange.zlib()

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.Compression.Zlib. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Compression
hmath_status hmath_interchange_value_zlib(hmath_context *context, hmath_value **out);

compress

interchange.compress(lim, wrapper, input)

Given limits,RawDeflate/Zlib/Gzip wrapper,then bytes, compress within a bounded output allocation. Return InterchangeError for unavailable provider, invalid limits, byte-budget excess or compression failure in IO.

Original: HMath.Interchange.Compression.compress. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Compression -> ByteString -> IO (Either InterchangeError ByteString)
hmath_status hmath_interchange_value_compress(hmath_context *context, const hmath_value *lim, const hmath_value *wrapper, const hmath_value *input, hmath_value **out);

compression_available

interchange.compression_available()

Probe whether the optional native zlib adapter is available, returning IO Bool. False means compressed operations cannot run; no payload is processed.

Original: HMath.Interchange.Compression.compressionAvailable. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

IO Bool
hmath_status hmath_interchange_value_compression_available(hmath_context *context, hmath_value **out);

decompress

interchange.decompress(value, value2, value3, value4)

The output length may be smaller than the budget. Archives additionally compare it to the declared member size before accepting their payload.

Original: HMath.Interchange.Compression.decompress. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Compression -> Int -> ByteString -> IO (Either InterchangeError ByteString)
hmath_status hmath_interchange_value_decompress(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, const hmath_value *value4, hmath_value **out);

raw_spec

interchange.raw_spec(dtype, endian, order, shape)

Construct or inspect the original immutable record; field order follows the source signature.

Original: HMath.Interchange.IO.RawSpec. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

DType -> Endian -> Order -> [Int] -> RawSpec
hmath_status hmath_interchange_value_raw_spec(hmath_context *context, const hmath_value *dtype, const hmath_value *endian, const hmath_value *order, const hmath_value *shape, hmath_value **out);

mapped_read_bytes

interchange.mapped_read_bytes(mapping, offset, count)

Copy a bounded byte range. Copies may safely survive mapping closure.

Original: HMath.Interchange.IO.mappedReadBytes. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

forall {k} (s :: k). MappedArray s -> Int -> Int -> IO (Either InterchangeError ByteString)
hmath_status hmath_interchange_value_mapped_read_bytes(hmath_context *context, const hmath_value *mapping, const hmath_value *offset, const hmath_value *count, hmath_value **out);

mapped_shape

interchange.mapped_shape(mapping)

Return dimensions of a callback-scoped read-only mapped array. The region token prevents its raw view escaping withMappedArray.

Original: HMath.Interchange.IO.mappedShape. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

forall {k} (s :: k). MappedArray s -> [Int]
hmath_status hmath_interchange_value_mapped_shape(hmath_context *context, const hmath_value *mapping, hmath_value **out);

mapped_value

interchange.mapped_value(mapping,indices, *, dtype="float64",boxed=False)

Read one typed scalar using checked multidimensional indexing. Physical endian conversion happens through the same Element decoder as normal arrays.

Original: HMath.Interchange.IO.mappedValue. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

forall {k} a (s :: k). Element a => MappedArray s -> [Int] -> IO (Either InterchangeError a)
hmath_status hmath_interchange_value_mapped_value(hmath_context *context, const hmath_value *prototype, const hmath_value *mapping, const hmath_value *indices, hmath_value **out);

read_array_file

interchange.read_array_file(lim, decode, path)

File reading checks the declared size before allocating, then caps the actual read too, handling concurrent growth. Files are closed before return.

Original: HMath.Interchange.IO.readArrayFile. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> (ByteString -> Either InterchangeError Array) -> FilePath -> IO (Either InterchangeError Array)
hmath_status hmath_interchange_value_read_array_file(hmath_context *context, const hmath_value *lim, const hmath_value *decode, const hmath_value *path, hmath_value **out);

read_raw_chunks

interchange.read_raw_chunks(value, value2, value3, value4, value5)

Read physical-order chunks (one-dimensional arrays); the caller retains the original RawSpec for reconstructing dimensions. Memory is O(chunk), excluding any data retained by the callback. False cancels successfully without consuming the rest. Full completion requires EOF, detecting tails.

Original: HMath.Interchange.IO.readRawChunks. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> RawSpec -> Int -> Handle -> (Array -> IO (Either InterchangeError Bool)) -> IO (Either InterchangeError ())
hmath_status hmath_interchange_value_read_raw_chunks(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, const hmath_value *value4, const hmath_value *value5, hmath_value **out);

with_mapped_array

interchange.with_mapped_array(limits, specification, path, callback)

Given limits,RawSpec,path,then rank-2 callback, map read-only raw data for that callback's lifetime and unmap on exit. Validate exact file size/spec/budgets; path/IO/format failures return InterchangeError. Do not retain borrowed pointers beyond the callback.

Original: HMath.Interchange.IO.withMappedArray. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> RawSpec -> FilePath -> (forall (s :: k). MappedArray s -> IO a) -> IO (Either InterchangeError a)
hmath_status hmath_interchange_value_with_mapped_array(hmath_context *context, const hmath_value *limits, const hmath_value *specification, const hmath_value *path, const hmath_value *callback, hmath_value **out);

write_array_file

interchange.write_array_file(lim, encode, path, a)

Writes to the supplied path after encoding succeeds. Applications needing transactional replacement can write a sibling temporary and rename it.

Original: HMath.Interchange.IO.writeArrayFile. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> (Limits -> Array -> Either InterchangeError ByteString) -> FilePath -> Array -> IO (Either InterchangeError ())
hmath_status hmath_interchange_value_write_array_file(hmath_context *context, const hmath_value *lim, const hmath_value *encode, const hmath_value *path, const hmath_value *a, hmath_value **out);

write_raw_chunks

interchange.write_raw_chunks(value, value2, value3, value4, value5)

Write fixed-size raw chunks. The producer receives a maximum byte count, must return whole elements, and signals EOF with Nothing. Short streams, overlong streams, noncanonical bools and empty nonfinal chunks fail. Errors may leave a partial output; the handle remains owned by the caller.

Original: HMath.Interchange.IO.writeRawChunks. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> RawSpec -> Int -> Handle -> (Int -> IO (Either InterchangeError (Maybe ByteString))) -> IO (Either InterchangeError ())
hmath_status hmath_interchange_value_write_raw_chunks(hmath_context *context, const hmath_value *value, const hmath_value *value2, const hmath_value *value3, const hmath_value *value4, const hmath_value *value5, hmath_value **out);

decode_npy

interchange.decode_npy(lim, input)

Given limits then NPY bytes, decode supported v1/v2/v3 fixed-width scalar dtype arrays. Reject pickle/object/record/string dtypes, malformed headers, unknown endian/layout, trailing bytes or exceeded budgets.

Original: HMath.Interchange.Numpy.decodeNpy. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_decode_npy(hmath_context *context, const hmath_value *lim, const hmath_value *input, hmath_value **out);

decode_npz

interchange.decode_npz(lim, input)

Checks directory/local consistency, CRC, exact deflate length, duplicate names, overlapping member ranges and aggregate expanded bytes. Data descriptors/encryption/multi-disk/ZIP64 directories are explicitly rejected.

Original: HMath.Interchange.Numpy.decodeNpz. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> ByteString -> IO (Either InterchangeError [(String, Array)])
hmath_status hmath_interchange_value_decode_npz(hmath_context *context, const hmath_value *lim, const hmath_value *input, hmath_value **out);

encode_npy

interchange.encode_npy(lim, order, a)

Given limits,physical C/F order,then Array, repack and write a NumPy NPY v1 payload with explicit dtype/endian/shape. Oversized header/output or unsupported layout conversion fails.

Original: HMath.Interchange.Numpy.encodeNpy. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Order -> Array -> Either InterchangeError ByteString
hmath_status hmath_interchange_value_encode_npy(hmath_context *context, const hmath_value *lim, const hmath_value *order, const hmath_value *a, hmath_value **out);

encode_npz

interchange.encode_npz(lim, compressed, arrays)

Deterministic archives, DOS epoch timestamps and no ZIP comments. True selects raw DEFLATE and requires the optional zlib build feature.

Original: HMath.Interchange.Numpy.encodeNpz. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Bool -> [(String, Array)] -> IO (Either InterchangeError ByteString)
hmath_status hmath_interchange_value_encode_npz(hmath_context *context, const hmath_value *lim, const hmath_value *compressed, const hmath_value *arrays, hmath_value **out);

decode_delimited

interchange.decode_delimited(lim, separator, dt, bs)

Given limits,comma/tab separator,target DType,then CSV/TSV bytes, parse rectangular real numeric cells to a rank-two Array. Complex dtype, malformed rows/tokens or exceeded budgets fail.

Original: HMath.Interchange.Text.decodeDelimited. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Char -> DType -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_decode_delimited(hmath_context *context, const hmath_value *lim, const hmath_value *separator, const hmath_value *dt, const hmath_value *bs, hmath_value **out);

decode_matrix_market

interchange.decode_matrix_market(lim, bs)

Array and coordinate input, real/integer/complex/pattern fields and general/symmetric/skew-symmetric/Hermitian storage. Coordinate duplicates are added exactly for integers and checked for finite overflow for floats. Dense output is bounded by maxElements even for sparse input.

Original: HMath.Interchange.Text.decodeMatrixMarket. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_decode_matrix_market(hmath_context *context, const hmath_value *lim, const hmath_value *bs, hmath_value **out);

decode_text

interchange.decode_text(lim, bs)

Given limits then HMath text bytes, parse dtype/shape/tokens and return a checked Array. Invalid ASCII/header/value counts or exceeded budgets fail.

Original: HMath.Interchange.Text.decodeText. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> ByteString -> Either InterchangeError Array
hmath_status hmath_interchange_value_decode_text(hmath_context *context, const hmath_value *lim, const hmath_value *bs, hmath_value **out);

encode_delimited

interchange.encode_delimited(lim, separator, a)

Given limits,comma or tab separator,then rank-two noncomplex Array, encode CSV/TSV numeric cells. No shape/dtype metadata is embedded; unsupported input/separator or output bounds fail.

Original: HMath.Interchange.Text.encodeDelimited. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Char -> Array -> Either InterchangeError ByteString
hmath_status hmath_interchange_value_encode_delimited(hmath_context *context, const hmath_value *lim, const hmath_value *separator, const hmath_value *a, hmath_value **out);

encode_matrix_market

interchange.encode_matrix_market(lim, a)

Dense general Matrix Market; exact Int64, Float64, or Complex128.

Original: HMath.Interchange.Text.encodeMatrixMarket. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Array -> Either InterchangeError ByteString
hmath_status hmath_interchange_value_encode_matrix_market(hmath_context *context, const hmath_value *lim, const hmath_value *a, hmath_value **out);

encode_text

interchange.encode_text(lim, a)

Given limits then Array, encode self-describing HMath text with dtype/shape and scalar tokens. Invalid/unsupported values or output exceeding limits returns InterchangeError.

Original: HMath.Interchange.Text.encodeText. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Array -> Either InterchangeError ByteString
hmath_status hmath_interchange_value_encode_text(hmath_context *context, const hmath_value *lim, const hmath_value *a, hmath_value **out);

bounded_int

interchange.bounded_int(name, upper, x)

Given diagnostic name,nonnegative upper bound,then Integer value, convert only if value lies in [0,upper] and fits Int. Otherwise return LimitExceeded with that name.

Original: HMath.Interchange.Array.boundedInt. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

String -> Integer -> Integer -> Either InterchangeError Int
hmath_status hmath_interchange_value_bounded_int(hmath_context *context, const hmath_value *name, const hmath_value *upper, const hmath_value *x, hmath_value **out);

byte_offsets

interchange.byte_offsets(a)

Return backing byte offsets for each logical element in row-major coordinate order, honoring signed strides and offset.

Original: HMath.Interchange.Array.byteOffsets. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Array -> [Int]
hmath_status hmath_interchange_value_byte_offsets(hmath_context *context, const hmath_value *a, hmath_value **out);

check_limits

interchange.check_limits(lim)

Validate nonnegative finite resource caps, rank<=255 and Int-safe byte/element/metadata/archive budgets. Invalid settings return InvalidData.

Original: HMath.Interchange.Array.checkLimits. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Limits -> Either InterchangeError ()
hmath_status hmath_interchange_value_check_limits(hmath_context *context, const hmath_value *lim, hmath_value **out);

guard_i

interchange.guard_i(p, e)

Given condition then InterchangeError, return Right () when True and Left that error otherwise. This helper performs no IO.

Original: HMath.Interchange.Array.guardI. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Bool -> InterchangeError -> Either InterchangeError ()
hmath_status hmath_interchange_value_guard_i(hmath_context *context, const hmath_value *p, const hmath_value *e, hmath_value **out);

run_decoder

interchange.run_decoder(parser, data, *, boxed=False)

Strict, exact decoder: trailing bytes are an error rather than ignored.

Original: HMath.Interchange.Binary.runDecoder. Python keeps the source argument order; Element-polymorphic helpers use dtype= instead of a type annotation.

Get a -> ByteString -> Either InterchangeError a
hmath_status hmath_interchange_value_run_decoder(hmath_context *context, const hmath_value *parser, const hmath_value *data, hmath_value **out);

dtype_code

interchange.dtype_code(dtype)

Return the original DType enumeration code as an integer (Bool8=0 through C128=12).

hmath_status hmath_interchange_value_dtype_code(hmath_context *context, const hmath_value *dtype, hmath_value **out);

error_fields

interchange.error_fields(error)

Return an InterchangeError's original constructor code and full message; embedded NUL and Unicode are retained.

hmath_status hmath_interchange_value_error_fields(hmath_context *context, const hmath_value *error, hmath_value **out);

put_bytes

interchange.put_bytes(program)

Execute the original Put program and return owned Bytes. This does not perform file IO.

hmath_status hmath_interchange_value_put_bytes(hmath_context *context, const hmath_value *program, hmath_value **out);

open_handle

interchange.open_handle(path, mode)

Open a real binary handle. Modes are rb, wb, ab or r+b; wb truncates and ab appends. IO failures raise the original InterchangeIOError. Close the shared resource explicitly before releasing its value owner.

hmath_status hmath_interchange_value_open_handle(hmath_context *context, const hmath_value *path, const hmath_value *mode, hmath_value **out);

close_handle

interchange.close_handle(handle)

Close the shared Haskell handle. Other retained owners refer to that same closed resource. Python BinaryHandle.close() closes the resource and releases its own value reference.

hmath_status hmath_interchange_value_close_handle(hmath_context *context, const hmath_value *handle, hmath_value **out);

seek_handle

interchange.seek_handle(handle, whence, offset)

Seek the binary handle with whence 0 (absolute), 1 (relative) or 2 (from end) and an exact integer byte offset. Original handle IO errors become InterchangeIOError.

hmath_status hmath_interchange_value_seek_handle(hmath_context *context, const hmath_value *handle, const hmath_value *whence, const hmath_value *offset, hmath_value **out);

tell_handle

interchange.tell_handle(handle)

Return the handle's current byte position as an exact integer.

hmath_status hmath_interchange_value_tell_handle(hmath_context *context, const hmath_value *handle, hmath_value **out);

flush_handle

interchange.flush_handle(handle)

Flush the original Haskell handle. This has the source hFlush contract and does not promise a filesystem durability barrier.

hmath_status hmath_interchange_value_flush_handle(hmath_context *context, const hmath_value *handle, hmath_value **out);

equal_array

interchange.equal_array(left, right)

Compare the original Array values, including dtype, endian, layout, metadata and backing bytes. This is structural equality, not a converted numerical comparison.

hmath_status hmath_interchange_value_equal_array(hmath_context *context, const hmath_value *left, const hmath_value *right, hmath_value **out);