Skip to content

Instantly share code, notes, and snippets.

@mkulke
Last active March 3, 2019 16:21
Show Gist options
  • Save mkulke/7c253cef2e040d40e4cbf7e76594bc44 to your computer and use it in GitHub Desktop.
Save mkulke/7c253cef2e040d40e4cbf7e76594bc44 to your computer and use it in GitHub Desktop.
future example using ts-monads
import * as future from './future';
import * as result from './result';
import { get } from 'https';
interface Tuple {
name: string;
len: number;
}
function printTuple(tuple: Tuple): void {
const { name, len } = tuple;
console.log('name: %s, posts: %i', name, len);
}
function printError(err: Error): void {
console.error('error: %s', err.message);
}
type Parser<T> = (s: string) => result.Result<T>;
type Getter<T> = (rj: (e: Error) => void, rs: (t: T) => void) => void;
function buildGetter<T>(url: string, parse: Parser<T>): Getter<T> {
return (rj, rs) => {
return get(url, resp => {
let data = '';
resp.on('data', chunk => data += chunk);
resp.on('end', () => {
const parsed = parse(data);
if (result.isOk(parsed)) {
const value = parsed.val;
rs(value);
} else {
rj(parsed.err);
}
});
}).on("error", rj);
};
}
function parseObject(data: string): result.Result<any> {
try {
const obj = JSON.parse(data);
return result.ok(obj);
} catch {
return result.err(new Error('could not parse json'));
}
}
function parseName(data: string): result.Result<string> {
return result.flatMap(obj => {
const name = obj.name;
if (typeof name === "string") {
return result.ok(obj.name);
}
return result.err(new Error('name not a string'));
}, parseObject(data));
}
// function parseName(data: string): result.Result<string> {
// try {
// const name: unknown = JSON.parse(data).name;
// if (typeof name === "string") {
// return result.ok(name);
// }
// return result.err(new Error('name not a string'));
// } catch {
// return result.err(new Error('could not parse name'));
// }
// }
function parseCount(data: string): result.Result<number> {
return result.flatMap(obj => {
if (obj instanceof Array) {
return result.ok(obj.length);
}
return result.err(new Error('data is not an array'));
}, parseObject(data));
}
// function parseCount(data: string): result.Result<number> {
// try {
// const posts: unknown = JSON.parse(data);
// if (posts instanceof Array) {
// return result.ok(posts.length);
// }
// return result.err(new Error('data is not an array'));
// } catch {
// return result.err(new Error('could not parse length'));
// }
// }
const getName = buildGetter('https://jsonplaceholder.typicode.com/users/2', parseName);
const getCount = buildGetter('https://jsonplaceholder.typicode.com/posts?userId=2', parseCount);
// function getUser(rj: (e: Error) => void, rs: (s: string) => void): void {
// get('https://jsonplaceholder.typicode.com/users/1', (resp) => {
// let data = '';
// resp.on('data', (chunk) => {
// data += chunk;
// });
// resp.on('end', () => {
// rs(JSON.parse(data).name);
// });
// }).on("error", rj);
// }
// function getPosts(rj: (e: Error) => void, rs: (s: number) => void): void {
// get('https://jsonplaceholder.typicode.com/posts?userId=1', resp => {
// let data = '';
// resp.on('data', chunk => {
// data += chunk;
// });
// resp.on('end', () => {
// rs(JSON.parse(data).length);
// });
// }).on("error", rj);
// }
const nameF = future.future(getName);
const tupleF = future.flatMap((name: string) => {
const postsF = future.future(getCount);
return future.map(len => ({ name, len}), postsF);
}, nameF);
future.fork(printError, printTuple, tupleF);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment