Glen Whitney
6f44567306
And also enhances the reflected type parsing so that the types of all implementations so far will parse.
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
import {joinTypes, typeOfDependency} from '../core/Dispatcher.js'
|
|
import type {
|
|
ZeroType, OneType, NaNType, Dependencies, Signature, Returns
|
|
} from '../interfaces/type.js'
|
|
import {$reflect} from '../interfaces/type.js'
|
|
|
|
export type Complex<T> = { re: T; im: T; }
|
|
|
|
export const Complex_type = {
|
|
name: 'Complex', // just until we have reflection to tell us
|
|
test: <T>(dep: { testT: (z: unknown) => z is T }) =>
|
|
(z: unknown): z is Complex<T> =>
|
|
typeof z === 'object' && z != null && 're' in z && 'im' in z
|
|
&& dep.testT(z['re']) && dep.testT(z['im']),
|
|
infer: (dep: typeOfDependency) =>
|
|
(z: Complex<unknown>) => joinTypes(dep.typeOf(z.re), dep.typeOf(z.im)),
|
|
from: {
|
|
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) })
|
|
}
|
|
}
|
|
|
|
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)
|
|
|
|
$reflect!([complex, zero, one, nan, re])
|