Skip to content

Instantly share code, notes, and snippets.

@richdouglasevans
Forked from i-am-tom/bifunctor-profunctor.js
Last active November 1, 2018 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save richdouglasevans/891564c2d13363b46e49187f28a28ae8 to your computer and use it in GitHub Desktop.
Save richdouglasevans/891564c2d13363b46e49187f28a28ae8 to your computer and use it in GitHub Desktop.
The main examples from the "Bifunctor + Profunctor" post.
const { Left, Right } = require("fantasy-eithers");
const daggy = require("daggy");
Function.prototype.map = function(f) {
return x => f(this(x));
};
//- Where everything changes...
const login = user => (user.name == "Tom" ? Right(user) : Left("Boo"));
//- Function map === "piping".
//+ failureStream :: String
//+ -> HTML
const failureStream = (x => x.toUpperCase())
.map(x => x + "!")
.map(x => "<em>" + x + "</em>");
//+ successStream :: User
//+ -> HTML
const successStream = (x => x.name)
.map(x => "Hey, " + x + "!")
.map(x => "<h1>" + x + "</h1>");
const user = { name: "Tom" };
console.log(
//- We can now pass in our two
//- possible application flows
//- using `bimap`!
login(user).bimap(failureStream, successStream)
);
//- Fancy wrapping around a specific type
//- of function: an "f a" to a "b"
//+ Costar f a b = f a -> b
const Costar = daggy.tagged("Costar", ["run"]);
//- Contramap with the "before" function,
//- fold, then apply the "after" function.
//+ promap :: Functor f
//+ => Costar f b c
//+ -> (b -> a, c -> d)
//+ -> Costar f a d
Costar.prototype.promap = function(f, g) {
return Costar(x => g(this.run(x.map(f))));
};
//- Takes a list of ints to the sum
//+ sum :: Costar Array Int Int
const sum = Costar(xs => xs.reduce((x, y) => x + y, 0));
//- Make every element 1, then sum them!
const length = sum.promap(_ => 1, x => x);
//- Is the result over 5?
const isOk = sum.promap(x => x, x => x > 5);
//- Why not both? Is the length over 5?
const longEnough = sum.promap(_ => 1, x => x > 5);
console.log(
// Returns false!
longEnough.run([1, 3, 5, 7])
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment