Skip to content

Instantly share code, notes, and snippets.

View DrBoolean's full-sized avatar

Brian Lonsdorf DrBoolean

View GitHub Profile
@DrBoolean
DrBoolean / debug.md
Last active July 30, 2018 18:15
Debugging Functional post

Debugging Functional

What's the problem

When working with ramda or lodash-fp, one may run into some rather cryptic error messages. When trying to console.log a function we're presented with the guts of some internal curry or compose implementation that tells us nothing. At Loop/Recur we enjoy working with Functional JavaScript so I'd like to see this improve.

This post will demonstrate a simple solution that can go a long way to enhance the debugging experience in functional JavaScript applications.

Test subjects

@DrBoolean
DrBoolean / SumProductList.js
Last active March 27, 2018 20:54
Either and Tuple (the canonical Sum/Product types, respectively) used to make a List
const {Left, Right} = require('data.either')
const Tuple = require('fantasy-tuples').Tuple2
//List :: Either Null (Tuple a List)
const empty = () =>
Left(null)
const cons = (x, l) =>
Right(Tuple(x, l))
const Reader = f =>
({
 run: f,
 map: g => Reader(x => g(f(x))),
 chain: g => Reader(x => g(f(x)).run(x))
})
Reader.of = x => Reader(() => x)
// function application
@DrBoolean
DrBoolean / lens7.js
Created January 21, 2016 17:29
Lens7
const immLens = key => lens((x) => x.get(key), (val, x) => x.set(key, val))
@DrBoolean
DrBoolean / free-er2.js
Created February 27, 2016 16:38
Free(er) Monads Pt2
const daggy = require('daggy')
const Task = require('data.task')
const _ = require('lodash')
const kleisli_comp = (f, g) => x => f(x).chain(g)
const compose = (f, g) => x => f(g(x))
const id = x => x
//=============FREE=============
const Free = daggy.taggedSum({Impure: ['x', 'f'], Pure: ['x']})
const {Impure, Pure} = Free
// build the empty ui data structure
const empty = from(x => x)
// a function that returns a complete component instead of a map that loops through all
const ui = Reader(to(empty)).map(loadComponent).map(addExample).map(beautifyHtml).map(addSelectorTable)
// run the function for a component
ui.run(‘buttons’) // {name: ‘Button’, example: ReactElement}
// create an empty ui
const empty = from(x => x)
// make a function to get the loaded up component
const ui = to(empty).map(loadComponent).map(addExample).map(beautifyHtml).map(addSelectorTable)
// run the function on the index we want
ui(‘buttons’) // {name: ‘Button’, example: ReactElement}
// create empty ui
const empty = Components.reduce((acc, key) => acc.set(key, key), Immutable.Map())
// load every component with every example and data filled in
const ui = empty.map(loadComponent).map(addExample).map(beautifyHtml).map(addSelectorTable)
// get the componet we want for the page
ui.get(‘buttons’) // {name: ‘Button’, example: ReactElement}
const Components = [‘alert’, ‘buttons’, ‘data-tables’, /* …etc */]
// from :: (Component -> a) -> UI
const from = f =>
 Components.reduce((ui, key) => ui.set(key, f(key)), Immutable.Map())
// to :: UI -> (Component -> a)
const to = structure =>
 key => structure.get(key)
const Pair = (x, y) =>
({
 _0: x,
 _1: y,
 map: f => Pair(x, f(y))
})
// to :: Pair a -> (Bool -> a)
const to = ({_0, _1}) =>
 bool => bool ? _0 : _1