Skip to content

Instantly share code, notes, and snippets.

@aesedepece
Last active October 5, 2018 14:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aesedepece/18200991e05f564cae249e78442df99a to your computer and use it in GitHub Desktop.
Save aesedepece/18200991e05f564cae249e78442df99a to your computer and use it in GitHub Desktop.
const types: {[key: string]: string} = {
Object: "Object",
String: "String",
Float: "Float"
}
const ops: {[key: string]: string} = {
parseJSON: "parseJSON",
get: "get",
asFloat: "asFloat"
}
const TypeSystem = {
[types.String]: {
[ops.parseJSON]: types.Object
},
[types.Object]: {
[ops.get]: types.Object,
[ops.asFloat]: types.Float
},
[types.Float]: {}
}
type Call = {
f: string,
params: any,
}
type Script = Array<Call>
type HTTPGET = {
type: HTTPGET,
url: string,
script: Script
}
type RetrievalPath = HTTPGET
type RetrievalPhase = Array<RetrievalPath>
type Ok<T> = {
t: "Ok",
value: T,
}
type Err = {
t: "Err",
msg: string,
}
type MultiErr = {
t: "MultiErr",
errors: Array<string>,
}
type Result<T> = Ok<T> | Err | MultiErr
const callValidator = (inputType: string, call: Call): Result<string> => {
let res: Result<string>;
if (inputType in TypeSystem) {
const op = ops[call.f]
if (op) {
const returnType = TypeSystem[inputType][op]
if (returnType) {
res = { t: "Ok", value: returnType }
} else {
res = { t: "Err", msg: `Operator "${call.f}" does not exist on type ${inputType}` }
}
} else {
res = { t: "Err", msg: `Unknown "${call.f}" operator` }
}
} else {
res = { t: "Err", msg: `Unknown "${inputType}" input type` }
}
return res;
}
const scriptValidator = (script: Script): Result<string> => {
return script.reduce((acc: Result<string>, call: Call) => {
console.log("Acculumator is", acc, "Call is", call)
return acc.t === "Ok" && callValidator(acc.value, call) || acc
}, { t: "Ok" , value: types.String } as Ok<string>)
}
const retrievalPathValidator = (path: RetrievalPath): Result<string> => {
return scriptValidator(path.script)
}
const retrievalPhaseValidator = (phase: RetrievalPhase): Result<string> => {
let res: Result<string>;
if (phase.length > 0) {
const types = phase.map(retrievalPathValidator)
console.log("Types are", types)
res = types.reduce((acc: Result<string>, returnType: Result<string>) => {
let res = acc;
if (acc.t === "Ok") {
if (returnType.t === "Ok") {
if (returnType.value !== acc.value) {
res = { t: "MultiErr", errors: ["Not all branches return same types"] };
}
} else if (returnType.t === "Err") {
res = { t: "MultiErr", errors: [returnType.msg] };
}
} else if (returnType.t === "Err") {
res = { t: "MultiErr", errors: acc.t === "Err" ? [returnType.msg] : [...acc.errors, returnType.msg] }
}
return res;
}, types[0])
} else {
res = { t: "Err", msg: "No retrieval paths" }
}
return res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment