Declare implementations and dependencies via standard interfaces for operations #8
@ -19,9 +19,10 @@ export const Complex_type = {
|
||||
}
|
||||
}
|
||||
|
||||
type Binary<B> = [B, B]
|
||||
|
||||
export interface ComplexReturn<Params> {
|
||||
// Sadly, I can't think of a way to make some nice abbreviation operators
|
||||
// for these generic type specifications because TypeScript generics
|
||||
// can't take and use generic parameters, only fully instantiated types.
|
||||
complex: Params extends [infer U] ? Complex<U> // unary case
|
||||
: Params extends BBinary<infer B> ? Complex<B> // binary case
|
||||
: never
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
type TypeName = string
|
||||
type Parameter = TypeName
|
||||
type Signature = Parameter[]
|
||||
type InputSignature = Parameter[]
|
||||
type DependenciesType = Record<string, Function>
|
||||
|
||||
export type typeOfDependency = {typeOf: (x: unknown) => TypeName}
|
||||
@ -62,7 +62,11 @@ export interface ReturnTypes<Params> {}
|
||||
|
||||
// Helpers for specifying signatures
|
||||
|
||||
// A homogenous binary operation (comes up a lot)
|
||||
// A basic signature with concrete types
|
||||
export type Signature<CandidateParams, ActualParams, Returns> =
|
||||
CandidateParams extends ActualParams ? Returns : never
|
||||
|
||||
// A homogenous binary operation (comes up a lot, needs a better name?)
|
||||
// Typical usage: `foo_impl: Params extends BBinary<infer B> ? B : never`
|
||||
// says that this implementation takes two arguments, both of type B, and
|
||||
// returns the same type.
|
||||
@ -118,9 +122,9 @@ type SpecificationsGroup = Record<string, SpecObject>
|
||||
export class Dispatcher {
|
||||
installSpecification(
|
||||
name: string,
|
||||
signature: Signature,
|
||||
signature: InputSignature,
|
||||
returns: TypeName,
|
||||
dependencies: Record<string, Signature>,
|
||||
dependencies: Record<string, InputSignature>,
|
||||
behavior: Function // possible todo: constrain this type based
|
||||
// on the signature, return type, and dependencies. Not sure if
|
||||
// that's really possible, though.
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {configDependency} from '../core/Config.js'
|
||||
import {BBinary, Dependency, ImpType} from '../core/Dispatcher.js'
|
||||
import {Signature, Dependency, ImpType} from '../core/Dispatcher.js'
|
||||
import type {Complex} from '../Complex/type.js'
|
||||
|
||||
declare module "./type" {
|
||||
@ -7,7 +7,7 @@ declare module "./type" {
|
||||
// This description loses information: some subtypes like NumInt or
|
||||
// Positive are closed under addition, but this says that the result
|
||||
// of add is just a number, not still of the reduced type
|
||||
add: Params extends BBinary<number> ? number : never
|
||||
add: Signature<Params, [number, number], number>
|
||||
// Whereas this one would preserve information, but would lie
|
||||
// because it claims all subtypes of number are closed under addition,
|
||||
// which is not true for `1 | 2 | 3`, for example.
|
||||
@ -16,15 +16,15 @@ declare module "./type" {
|
||||
// : never
|
||||
//
|
||||
// Not sure how this will need to go when we introduce NumInt.
|
||||
unaryMinus: Params extends [number] ? number : never
|
||||
subtract: Params extends BBinary<number> ? number : never
|
||||
multiply: Params extends BBinary<number> ? number : never
|
||||
divide: Params extends BBinary<number> ? number : never
|
||||
unaryMinus: Signature<Params, [number], number>
|
||||
subtract: Signature<Params, [number, number], number>
|
||||
multiply: Signature<Params, [number, number], number>
|
||||
divide: Signature<Params, [number, number], number>
|
||||
// Best we can do for sqrt at compile time, since actual return
|
||||
// type depends on config. Not sure how this will play out
|
||||
// when we make a number-only bundle, but at least the import type
|
||||
// above for Complex<> does not lead to any emitted JavaScript.
|
||||
sqrt: Params extends [number] ? (number | Complex<number>) : never
|
||||
sqrt: Signature<Params, [number], number | Complex<number>>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,10 @@ export interface NumbersReturn<Params> {
|
||||
zero: Params extends [infer T]
|
||||
? T extends number ? 0 extends T ? 0 : never : never
|
||||
: never
|
||||
// Note that in any case the simple
|
||||
// zero: Signature<Params, [number], 0>
|
||||
// makes complex fail to compile, because it worries that you might be
|
||||
// making `Complex<Small>` where zero would not return the right type.
|
||||
}
|
||||
|
||||
export const zero: ImpType<'zero', [number]> = a => 0
|
||||
|
Loading…
Reference in New Issue
Block a user