Skip to content

Instantly share code, notes, and snippets.

@masaeedu
Created June 3, 2018 06:19
Show Gist options
  • Save masaeedu/6d0f874110591d63445e4b8aaf8cd068 to your computer and use it in GitHub Desktop.
Save masaeedu/6d0f874110591d63445e4b8aaf8cd068 to your computer and use it in GitHub Desktop.
require("@babel/polyfill");
const {
Fnctr,
Arr,
implement,
Functor,
Chain,
Apply
} = require("@masaeedu/fp");
const Cont = require("@masaeedu/fp/dist/instances/cont");
const fs = require("fs");
const FalsyFirstEither = (() => {
const Left = e => [e];
const Right = (...x) => [null, ...x];
const match = ({ Left, Right }) => ([e, ...x]) => (e ? Left(e) : Right(...x));
return { Left, Right, match };
})();
const GenericEitherT = ({ Left, Right, match }) => M => {
const of = x => M.of(Right(x));
const chain = f =>
match({
Left: l => M.of(Left(l)),
Right: r => f(r)
}) |> M.chain;
return (
{ of, chain }
|> implement(Chain)
|> implement(Apply)
|> implement(Functor)
|> implement(Apply) // lift2 depends on functor, so we have to do this twice. TODO: do dependency solving and get rid of this shit
);
};
const trim = s => s.trim();
{
const { of, map, chain } = GenericEitherT(FalsyFirstEither)(Cont);
const spreadify = f => (...args) => f(args);
const run = rawNodeAPI => (...args) => cb =>
rawNodeAPI(...args, spreadify(cb));
const fork = x =>
x(([err, ...data]) => {
if (err) throw err;
console.log(...data);
});
run(fs.writeFile)("foo.txt", "bar.txt")
|> chain(_ => run(fs.writeFile)("bar.txt", "This is a test."))
|> chain(_ => run(fs.readFile)("foo.txt", "utf8"))
|> map(trim)
|> chain(run(fs.readFile))
|> map(x => x.length)
|> fork; // => 15
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment