Skip to content

Instantly share code, notes, and snippets.

@rzeigler
Created June 25, 2019 14:02
Show Gist options
  • Save rzeigler/356912ed0a98d3d6cd4f4de7bbd9ac96 to your computer and use it in GitHub Desktop.
Save rzeigler/356912ed0a98d3d6cd4f4de7bbd9ac96 to your computer and use it in GitHub Desktop.
Using ReaderTaskEither from fp-ts
import * as http from "http";
import { ReaderTaskEither } from "fp-ts/lib/ReaderTaskEither"
import { TaskEither, fromIO } from "fp-ts/lib/TaskEither";
import { IO } from "fp-ts/lib/IO";
import { Task } from "fp-ts/lib/Task";
import axios, { AxiosInstance } from 'axios';
import { Either, left, right } from "fp-ts/lib/Either";
export type Logger = (s: string) => TaskEither<never, void>;
function consoleLogger(s: string): TaskEither<never, void> {
return fromIO(new IO(() => console.log(s)));
}
export interface WithLogger {
logger: Logger
}
export interface WithClient {
client: AxiosInstance
}
function log<E extends WithLogger, L = never>(s: string): ReaderTaskEither<E, L, void> {
return new ReaderTaskEither(e => e.logger(s))
}
function request<E extends WithClient>(s: string): ReaderTaskEither<E, string, string> {
return new ReaderTaskEither(e =>
new TaskEither(
new Task(
() =>
e.client.get<string>(s)
.then(r => right<string, string>(r.data))
.catch(e => left(e.toString())) as Promise<Either<string, string>>
)
));
}
export function getWithFallback<E extends WithLogger & WithClient>(primary: string, secondary: string): ReaderTaskEither<E, string, void> {
return request<E>(primary)
.orElse((e) => log<E, string>(`primary failed with ${e}`).applySecond(request<E>(secondary)))
.chain(result => log<E>(`result: ${result}`));
}
getWithFallback("http://www.google.com/does/not/exist", "http://www.google.com")
.run({
logger: consoleLogger,
client: axios
})
.then(e => console.log("end "))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment