Skip to content

Instantly share code, notes, and snippets.

@gtkatakura
Last active September 14, 2017 11:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gtkatakura/dab7999c7d706b7cd805bda2dfcb2ab6 to your computer and use it in GitHub Desktop.
Save gtkatakura/dab7999c7d706b7cd805bda2dfcb2ab6 to your computer and use it in GitHub Desktop.
// library or otherwise
// {
type Func<T, TResult> = (value: T) => TResult;
type Predicate<T> = Func<T, boolean>;
function compose<TIn, TMiddle, TOut>(f: Func<TMiddle, TOut>, g: Func<TIn, TMiddle>) {
return (value: TIn) => f(g(value));
}
function composeWith<TMiddle, TOut>(f: Func<TMiddle, TOut>) {
return <TIn>(g: Func<TIn, TMiddle>) => compose(f, g)
}
function pipe<TIn, TMiddle, TOut>(f: Func<TIn, TMiddle>, g: Func<TMiddle, TOut>) {
return (value: TIn) => g(f(value));
}
function add(left: number, right: number) {
return left + right;
}
function and<T>(predicates: Predicate<T>[]) {
return (value: T) => predicates.every(predicate => predicate(value));
}
function filter<T>(predicate: Predicate<T>) {
return (values: T[]) => values.filter(predicate);
}
function map<T, TResult>(transformation: Func<T, TResult>) {
return (values: T[]) => values.map(transformation);
}
function sum(values: number[]) {
return values.reduce(add, 0);
}
function average(values: number[]) {
return sum(values) / values.length;
}
// }
// business code
// {
class Employee {
constructor(public name: string, public salary: number) {}
}
class Department {
constructor(public employees: Employee[]) {}
works(employee: Employee) {
//return this.employees.includes(employee);
return this.employees.indexOf(employee) > -1;
}
}
const filterEmployees = compose<
Predicate<Employee>[],
Predicate<Employee>,
Func<Employee[], Employee[]>
>(filter, and);
const mapSalary = map((employee: Employee) => employee.salary);
const employeeSalaries = compose(
composeWith(mapSalary),
filterEmployees
);
const averageSalary = compose(
composeWith(average),
employeeSalaries
);
const empls = [
new Employee("Jim", 100),
new Employee("John", 200),
new Employee("Liz", 120),
new Employee("Penny", 30)
];
const sales = new Department([empls[0], empls[1]]);
const result = averageSalary([
e => e.salary > 50,
e => sales.works(e)
])(empls)
alert(result);
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment