import {joinTypes, typeOfDependency} from '../core/Dispatcher.js' import type { ZeroType, OneType, NaNType, Dependencies, Signature, Returns } from '../interfaces/type.js' export type Complex = { re: T; im: T; } export const Complex_type = { test: (dep: { testT: (z: unknown) => z is T }) => (z: unknown): z is Complex => typeof z === 'object' && z != null && 're' in z && 'im' in z && dep.testT(z['re']) && dep.testT(z['im']), infer: (dep: typeOfDependency) => (z: Complex) => joinTypes(dep.typeOf(z.re), dep.typeOf(z.im)), from: { T: (dep: Dependencies<'zero', T>) => (t: T) => ({ re: t, im: dep.zero(t) }), Complex: (dep: { convert: (from: U) => T }) => (z: Complex) => ({ re: dep.convert(z.re), im: dep.convert(z.im) }) } } declare module "../interfaces/type" { interface AssociatedTypes { Complex: T extends Complex ? { type: Complex zero: Complex> one: Complex | ZeroType> nan: Complex> real: RealType } : never } interface Signatures { complex: ((re: T) => Complex) | ((re: T, im: T) => Complex) } } export const complex = (dep: Dependencies<'zero', T>): Signature<'complex', T> => (a, b) => ({re: a, im: b || dep.zero(a)}) export const zero = (dep: Dependencies<'zero', T> & Dependencies<'complex', Returns<'zero', T>>): Signature<'zero', Complex> => z => dep.complex(dep.zero(z.re), dep.zero(z.im)) export const one = (dep: Dependencies<'one' | 'zero', T> & Dependencies<'complex', Returns<'one' | 'zero', T>>): Signature<'one', Complex> => z => dep.complex(dep.one(z.re), dep.zero(z.im)) export const nan = (dep: Dependencies<'nan', T> & Dependencies<'complex', Returns<'nan', T>>): Signature<'nan', Complex> => z => dep.complex(dep.nan(z.re), dep.nan(z.im)) export const re = (dep: Dependencies<'re', T>): Signature<'re', Complex> => z => dep.re(z.re)