Skip to content

Instantly share code, notes, and snippets.

@mrtnbroder
Forked from i-am-tom/traversable.js
Created November 1, 2018 09:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrtnbroder/4a46074f3c36a17702d5fc2886dcb09f to your computer and use it in GitHub Desktop.
Save mrtnbroder/4a46074f3c36a17702d5fc2886dcb09f to your computer and use it in GitHub Desktop.
A bunch of examples from the Traversable episode.
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' ]
// Let's pretend this does some AJAX...
const getById = id => new Task((rej, res) =>
queens[id] ? res(queens[id])
: rej('Out of range'))
const append = x => xs => [... xs, x]
// insideOut :: Applicative f
// => [f a] -> f [a]
const insideOut = (T, xs) => xs.reduce(
(acc, x) => lift2(append, x, acc),
T.of([]))
// paralleliseTaskArray :: [Int] -> Task e [User]
const paralleliseTaskArray = users =>
insideOut(Task, users.map(API.getById))
Array.prototype.traverse = function (T, f) {
return this.reduce(
// Here's the map bit! vvvv
(acc, x) => lift2(append, f(x), acc),
T.of([]))
}
const sequence = (T, xs) => xs.traverse(T, x => x)
// [ 'Alyssa', 'Katya' ]
;[0, 1].traverse(Task, getById)
.fork( e => console.log('ERROR')
, x => console.log(x) )
// toChar :: Int -> Either String Char
const toChar = n => n < 0 || n > 25
? Either.Left(n + ' is out of bounds!')
: Either.Right(String.fromCharCode(n + 65))
// Right(['A', 'B', 'C', 'D'])
console.log(
[0, 1, 2, 3]
.traverse(Either, toChar))
// Left('-2 is out of bounds!')
console.log(
[0, 15, 21, -2]
.traverse(Either, toChar))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment