Skip to content

Instantly share code, notes, and snippets.

@j1r1k
Created March 8, 2018 07:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j1r1k/150aee520d311311f59a1e11b4e9ff0c to your computer and use it in GitHub Desktop.
Save j1r1k/150aee520d311311f59a1e11b4e9ff0c to your computer and use it in GitHub Desktop.
Code from a ngParty talk @ 7th Mar 2018
const R = require("ramda");
const data = {
title: "Intro to functional lenses",
author: {
name: "Jiri Marsicek",
email: "jiri.marsicek@gmail.com",
position: {
name: "Software Engineer",
company: "MSD"
}
},
sections: [
{
title: "whoami",
points: [
'interested in functional programming (Haskell, Scala)',
'interested in static guarantees about software (strong static typing, formal verification)',
'wanabe full-stack'
]
},
{
title: "what is lens?",
points: [
'functional "getter" and "setter"',
"composable",
"focuses on the specific bit of a larger data structure",
"cannot change the shape of data structure outside of lens focus"
]
}
]
};
// declaration of lens
const titleLens = R.lens(R.prop('title'), R.assoc('title')) // helper: R.lensProp('title')
// getter part is triggered via 'view'
R.view(titleLens, data)
// setter part is triggered via 'set', creates a modified copy, does not mutate
const dataModified = R.set(titleLens, "Not an introduction", data)
R.view(titleLens, data)
R.view(titleLens, dataModified)
// lenses over elements of arrays
const firstSectionLens = R.lens(R.nth(1), R.update(1)) // helper: R.lensIndex(1)
JSON.stringify(R.view(firstSectionLens, data.sections))
// over changes data under focus of the lens with a function, creates a modified copy, does not mutate
const dataWithUppercaseTitle = R.over(titleLens, R.toUpper, data)
R.view(titleLens, dataWithUppercaseTitle)
const firstPointInFirstSectionLens = R.compose(R.lensProp('sections'), R.lensIndex(0), R.lensProp('points'), R.lensIndex(0)) // helper: R.lensPath('sections', 0, 'points', 0)
// in JavaScript lenses are structural (titleLens can be used over any object with title property)
R.view(titleLens, data.sections[0])
const state = {
tables: [
['1','2','3'],
['4','5','6']
]
}
const moveItem = state => (source, target, sourceIndex, targetIndex) => {
const { tables } = state;
const sourceData = tables[source];
const targetData = tables[target];
const sourceRow = sourceData[sourceIndex];
const targetRow = targetData[targetIndex];
const withReplacedSource = R.assoc(source, R.update(sourceIndex, targetRow, sourceData), tables);
const withReplacedTarget = R.assoc(target, R.update(targetIndex, sourceRow, withReplacedSource[target]), withReplacedSource);
return { tables: withReplacedTarget };
};
const modified = moveItem(state)(0,1,0,0)
const state = {
tables: [
['1','2','3'],
['4','5','6']
]
}
const moveItem = state => (sourceLens, targetLens) => {
const sourceRecord = R.view(sourceLens, state);
const targetRecord = R.view(targetLens, state);
const withReplacedSource = R.set(sourceLens, targetRecord, state);
const withReplacedTarget = R.set(targetLens, sourceRecord, withReplacedSource);
return withReplacedTarget
};
const tablesLens = R.lensProp('tables')
const sourceLens = R.compose(tablesLens, R.lensIndex(0), R.lensIndex(0))
const targetLens = R.compose(tablesLens, R.lensIndex(1), R.lensIndex(0))
const modified = moveItem(state)(sourceLens, targetLens)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment