refactor(Complex): Now a template type!
This means that the real and imaginary parts of a Complex must now be
the same type. This seems like a real benefit: a Complex with a number real
part and a bigint imaginary part does not seem sensible.
Note that this is now straining typed-function in (at least) the following
ways:
(1) In this change, it was necessary to remove the logic that the square root
of a negative number calls complex square root, which then calls back
to the number square root in its algorithm. (This was creating a circular
reference in the typed-function which the old implementation of Complex
was somehow sidestepping.)
(2) typed-function could not follow conversions that would be allowed by
uninstantiated templates (e.g. number => Complex<number> if the latter
template has not been instantiated) and so the facility for
instantiating a template was surfaced (and for example is called explicitly
in the demo loader `extendToComplex`. Similarly, this necessitated
making the unary signature of the `complex` conversion function explicit,
rather than just via implicit conversion to Complex.
(3) I find the order of implementations is mattering more in typed-function
definitions, implying that typed-function's sorting algorithm is having
trouble distinguishing alternatives.
But otherwise, the conversion went quite smoothly and I think is a good demo
of the power of this approach. And I expect that it will work even more
smoothly if some of the underlying facilities (subtypes, template types) are
integrated into typed-function.
This commit is contained in:
parent
845a2354c9
commit
1444b9828f
25 changed files with 240 additions and 157 deletions
|
|
@ -1,5 +1,8 @@
|
|||
export * from './Types/Complex.mjs'
|
||||
|
||||
export const abs = {
|
||||
Complex: ({sqrt, 'absquare(Complex)': absq}) => z => sqrt(absq(z))
|
||||
'Complex<T>': ({
|
||||
'sqrt(T)': sqt,
|
||||
'absquare(Complex<T>)': absq
|
||||
}) => z => sqt(absq(z))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue