Skip to content

Instantly share code, notes, and snippets.

@kayac-chang
Created January 31, 2022 05:18
Show Gist options
  • Save kayac-chang/3727da9f78b4e3284831bd10f96b37dd to your computer and use it in GitHub Desktop.
Save kayac-chang/3727da9f78b4e3284831bd10f96b37dd to your computer and use it in GitHub Desktop.
[learn FP with Kirby using `fp-ts`] TaskEither
/**
* chain and orElse
* ===
* sequential asynchronous processing can combined with chain and orElse
*/
import { pipe } from "fp-ts/lib/function";
import {
chain,
tryCatch,
orElse,
fold,
left,
TaskEither,
} from "fp-ts/lib/TaskEither";
/**
* Scenerio. Two phase commit
*/
namespace transaction {
export declare const begin: TaskEither<Error, void>;
export declare const second: TaskEither<Error, void>;
export declare const rollback: TaskEither<Error, void>;
}
pipe(
tryCatch(
// try begin transaction
transaction.begin,
(err) => new Error(`begin txn failed: ${err}`)
),
chain(() =>
tryCatch(
// if begin transaction success, try second transaction
transaction.second,
(err) => new Error(`commit txn failed: ${err}`)
)
),
orElse((originalError) =>
pipe(
tryCatch(
// if begin or second transaction failed, try rollback transaction
transaction.rollback,
(err) => new Error(`rollback txn failed: ${err}`)
),
fold(
// if rollback failed, return rollback error
left,
// rollback success, return original error
() => left(originalError)
)
)
)
);
/**
* fold (match)
* ===
* use `fold` for pattern matching which task success or failed
*/
import { pipe } from "fp-ts/lib/function";
import { Task } from "fp-ts/lib/Task";
import { tryCatch, TaskEither, fold } from "fp-ts/lib/TaskEither";
declare const taskMaybeFailed: TaskEither<Error, void>;
declare const onSuccess: () => Task<void>;
declare const onFailed: (err: Error) => Task<void>;
pipe(
tryCatch(
taskMaybeFailed,
(reason) => new Error(String(reason))
//
),
fold(
onFailed,
onSuccess
//
)
);
/**
* TaskEither
* ===
* We already know
* Task - an asynchronous operation that can't fail
* Either - synchronous operation that can fail
*
* So combine together
* TaskEither -
* an asynchronous operation that can fail
*/
import axios from "axios";
import { pipe } from "fp-ts/lib/function";
import { tryCatch, map } from "fp-ts/lib/TaskEither";
async function main() {
await describe("Making a http request which return 200", async () => {
const result = await pipe(
tryCatch(
() => axios.get("https://httpstat.us/200"),
(reason) => new Error(String(reason))
),
map((res) => res.data)
)();
console.log(result);
});
await describe("Same code with previous but return 500", async () => {
const result = await pipe(
tryCatch(
() => axios.get("https://httpstat.us/500"),
(reason) => new Error(String(reason))
),
map((res) => res.data)
)();
console.log(result);
});
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment