Skip to content

Instantly share code, notes, and snippets.

@Danny02
Created March 26, 2018 11:14
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 Danny02/a30b983a12354801deed75fa8114f807 to your computer and use it in GitHub Desktop.
Save Danny02/a30b983a12354801deed75fa8114f807 to your computer and use it in GitHub Desktop.
class SchuleQuery {
constructor(public art: string, public name: string, public addresse: string, public plz: string) {
}
}
type SchuleValidator = Validator<Partial<SchuleQuery>, string>;
const minOne: SchuleValidator = ps => {
if (Object.keys(ps).find(f => f !== undefined)) {
return new Success(ps);
} else {
return new Failure('no field is set');
}
};
const plzAndAddress: SchuleValidator = ps => {
if (ps.plz && !ps.addresse) {
return new Failure('plz set but address is not');
}
if (ps.addresse && !ps.plz) {
return new Failure('address set but plz is not');
}
return new Success(ps);
};
const schulenValidator = aggregate(minOne, plzAndAddress)
class Success<R> {
constructor(readonly value: R) {
}
}
class Failure<E> {
constructor(readonly error: E) {
}
}
type Validation<R, E> = Success<R> | Failure<E>;
type ValNel<R, E> = Validation<R, E[]>;
type Validator<R, E> = (r: R) => Validation<R, E>;
function lift<R, E>(v: Validation<R, E>): ValNel<R, E> {
return v instanceof Success ? v : new Failure([v.error]);
}
function combine<R, E>(a: ValNel<R, E>, b: ValNel<R, E>): ValNel<R, E> {
if (a instanceof Failure) {
if (b instanceof Failure) {
return new Failure(b.error.concat(a.error));
} else {
return a;
}
} else {
return b;
}
}
function aggregate<R, E>(...validators: Validator<R, E>[]): (r: R) => ValNel<R, E> {
return (r: R) => {
const validated: Validation<R, E>[] = validators.map(v => v.apply(r));
const lifted: ValNel<R, E>[] = validated.map(lift);
return lifted.reduce(combine);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment