2023-01-22 01:34:57 +00:00
|
|
|
import {joinTypes, typeOfDependency} from '../core/Dispatcher.js'
|
|
|
|
import type {
|
|
|
|
ZeroType, OneType, NaNType, Dependencies, Signature, Returns
|
|
|
|
} from '../interfaces/type.js'
|
2022-12-07 01:21:05 +00:00
|
|
|
|
2023-01-22 01:34:57 +00:00
|
|
|
export type Complex<T> = { re: T; im: T; }
|
2022-12-07 01:21:05 +00:00
|
|
|
|
|
|
|
export const Complex_type = {
|
2023-08-26 02:15:59 +00:00
|
|
|
name: 'Complex', // just until we have reflection to tell us
|
2023-01-22 01:34:57 +00:00
|
|
|
test: <T>(dep: { testT: (z: unknown) => z is T }) =>
|
2022-12-07 01:21:05 +00:00
|
|
|
(z: unknown): z is Complex<T> =>
|
2023-01-22 01:34:57 +00:00
|
|
|
typeof z === 'object' && z != null && 're' in z && 'im' in z
|
|
|
|
&& dep.testT(z['re']) && dep.testT(z['im']),
|
2022-12-19 22:14:26 +00:00
|
|
|
infer: (dep: typeOfDependency) =>
|
2022-12-07 01:21:05 +00:00
|
|
|
(z: Complex<unknown>) => joinTypes(dep.typeOf(z.re), dep.typeOf(z.im)),
|
|
|
|
from: {
|
2023-01-22 01:34:57 +00:00
|
|
|
T: <T>(dep: Dependencies<'zero', T>) => (t: T) =>
|
|
|
|
({ re: t, im: dep.zero(t) }),
|
|
|
|
Complex: <U, T>(dep: { convert: (from: U) => T }) =>
|
|
|
|
(z: Complex<U>) => ({ re: dep.convert(z.re), im: dep.convert(z.im) })
|
2022-12-07 01:21:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-22 01:34:57 +00:00
|
|
|
declare module "../interfaces/type" {
|
|
|
|
interface AssociatedTypes<T> {
|
|
|
|
Complex: T extends Complex<infer R> ? {
|
|
|
|
type: Complex<R>
|
|
|
|
zero: Complex<ZeroType<R>>
|
|
|
|
one: Complex<OneType<R> | ZeroType<R>>
|
|
|
|
nan: Complex<NaNType<R>>
|
|
|
|
real: RealType<R>
|
|
|
|
} : never
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Signatures<T> {
|
|
|
|
complex: ((re: T) => Complex<T>) | ((re: T, im: T) => Complex<T>)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const complex =
|
|
|
|
<T>(dep: Dependencies<'zero', T>): Signature<'complex', T> =>
|
|
|
|
(a, b) => ({re: a, im: b || dep.zero(a)})
|
|
|
|
|
|
|
|
export const zero =
|
|
|
|
<T>(dep: Dependencies<'zero', T>
|
|
|
|
& Dependencies<'complex', Returns<'zero', T>>):
|
|
|
|
Signature<'zero', Complex<T>> =>
|
|
|
|
z => dep.complex(dep.zero(z.re), dep.zero(z.im))
|
|
|
|
|
|
|
|
export const one =
|
|
|
|
<T>(dep: Dependencies<'one' | 'zero', T>
|
|
|
|
& Dependencies<'complex', Returns<'one' | 'zero', T>>):
|
|
|
|
Signature<'one', Complex<T>> =>
|
|
|
|
z => dep.complex(dep.one(z.re), dep.zero(z.im))
|
|
|
|
|
|
|
|
export const nan =
|
|
|
|
<T>(dep: Dependencies<'nan', T>
|
|
|
|
& Dependencies<'complex', Returns<'nan', T>>):
|
|
|
|
Signature<'nan', Complex<T>> =>
|
|
|
|
z => dep.complex(dep.nan(z.re), dep.nan(z.im))
|
|
|
|
|
|
|
|
export const re =
|
|
|
|
<T>(dep: Dependencies<'re', T>): Signature<'re', Complex<T>> =>
|
|
|
|
z => dep.re(z.re)
|