This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simple example, but the idea holds for more complex objects. | |
/* 1) Start with OO */ | |
// user.js | |
class User { | |
constructor(firstName, lastName, email) { | |
this.firstName = firstName | |
this.lastName = lastName |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Utils | |
const range = n => [...Array(n).keys()]; | |
const add = ([x0, y0]) => ([x1, y1]) => [x0 + x1, y0 + y1]; | |
const rotate = θ => ([x, y]) => [ | |
Math.round(x * Math.cos(θ) - y * Math.sin(θ)), | |
Math.round(x * Math.sin(θ) + y * Math.cos(θ)) | |
]; | |
const map = f => g => | |
function*() { | |
for (const v of g()) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This gist shows how to factor a concrete stateful fold in vanilla JS | |
// into a number of general purpose utilities that can be combined to recover | |
// the original behavior | |
// We're going to start from a particular code snippet and iteratively make | |
// small changes to it to get a finished product | |
// While reading this post, it is useful to have a diff tool at hand that allows | |
// you to compare snippets side by side and see what changed in each iteration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sometimes, you might want to supply *some* config, but | |
// not necessarily *all*. Maybe your password is really | |
// secret, so you don't want to risk saving it in a config | |
// file. In which case, you'll want to ask the user to enter | |
// it when your script runs. | |
// This interface provides a flexible approach, where | |
// the user is prompted for a missing key when it's | |
// requested - if a particular key isn't needed for a given | |
// run, the user won't need to enter it. Of course, if the |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fl = require('fantasy-land') | |
//- Lazy holds a vaue in a thunk, effectively delaying | |
//- evaluation until required. This is useful when we're | |
//- in a situation with either very large data set or | |
//- cyclical data. | |
//@ make stack-safe. | |
//> type Lazy a = Unit -> a | |
function Lazy(run) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const daggy = require('daggy') | |
const { uncurryN } = require('wi-jit') // Shameless plug :-) | |
// We'll need these instances for an example later... | |
Function.prototype.map = function (that) { | |
return x => that(this(x)) | |
} | |
Function.prototype.ap = function (that) { | |
return x => that(x)(this(x)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Task = require('data.task') | |
const Either = require('fantasy-eithers') | |
// data.task actually uses `ap` with reversed | |
// arguments, as the spec originally did, so | |
// this is an "old-fashioned" lift2. | |
const lift2 = (f, a, b) => a.map(f).ap(b) | |
const queens = [ 'Alyssa', 'Katya', 'Willam' ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fl = require('fantasy-land') | |
//- Textbook rose tree. | |
//+ type RoseTree a = { value :: a, children :: [RoseTree a] } | |
function RoseTree(value, children) { | |
if (this.constructor !== RoseTree) | |
return new RoseTree(value, children) | |
Object.assign(this, { value, children }) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Future = require('fluture') | |
// I can't guarantee this will work out of the box - it's quite old... but | |
// you should hopefully be able to see how this fits together! | |
const { ReaderT } = require('fantasy-readers') | |
// First of all, you're going to need to "lift" all your `Future` operations | |
// to work within ReaderT. Basically, you just need to call `ReaderT.lift` on | |
// any `Future` values. | |
const doAjaxThing_ = x => ReaderT.lift(doAjaxThing(x)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { tagged } from "daggy"; | |
const First = tagged("First", ["val"]); | |
First.prototype.concat = function(that) { | |
return this; | |
}; | |
const Min = tagged("Min", ["val"]); |
NewerOlder