Skip to content

Instantly share code, notes, and snippets.

@baetheus
Created May 21, 2019 01:07
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 baetheus/2867dd568fc129398f2d8f950876d914 to your computer and use it in GitHub Desktop.
Save baetheus/2867dd568fc129398f2d8f950876d914 to your computer and use it in GitHub Desktop.
Playing with monocle-ts
import { array } from 'fp-ts/lib/Array';
import { fromNullable, none, Option, some } from 'fp-ts/lib/Option';
import { fromTraversable, Lens, Optional, Prism } from 'monocle-ts';
/* Interfaces */
interface Bug {
bugId: number;
description: Option<string>;
}
interface User {
userId: number;
bugs: Option<Bug[]>;
}
interface State {
users: Record<string, User>;
}
/* Raw Optics */
const stateL = Lens.fromProp<State>();
const usersL = stateL('users');
const usersO = Optional.fromNullableProp<Record<string, User>>();
const userL = Lens.fromProp<User>();
const bugsO = Optional.fromOptionProp<User>()('bugs');
const bugsT = fromTraversable(array)<Bug>();
const getBugPrism = (id: number): Prism<Bug, Bug> =>
Prism.fromPredicate(bug => bug.bugId === id);
const getBugOptional = (id: number) =>
new Optional<Bug[], Bug>(
bs => fromNullable(bs.find(b => b.bugId === id)),
b => bs => {
let found = false;
const out = bs.map(_b => {
if (_b.bugId === id) {
found = true;
console.log('FOUND');
return b;
}
console.log('NOTFOUND');
return _b;
});
if (!found) {
console.log('PUSHING');
out.push(b);
}
return out;
}
);
/* Modified Optics */
const bugsL = new Lens<User, Bug[]>(
u => u.bugs.getOrElse([]),
bs => u =>
Object.assign({}, u, {
bugs: u.bugs.fold(some(bs), _bs => some(_bs.concat(bs))),
})
);
/* Composed Optics */
const getUserO = (userId: number) =>
usersL.composeOptional(usersO(String(userId)));
const getBugT = (userId: number, bugId: number) =>
getUserO(userId)
.composeOptional(bugsO)
.composeTraversal(bugsT)
.composePrism(getBugPrism(bugId));
const getBugLTP = (userId: number, bugId: number) =>
getUserO(userId)
.composeLens(bugsL)
.composeTraversal(bugsT)
.composePrism(getBugPrism(bugId));
const getBugO = (userId: number, bugId: number) =>
getUserO(userId)
.composeLens(bugsL)
.composeOptional(getBugOptional(bugId));
const state: State = {
users: {
'1': {
userId: 1,
bugs: none,
},
'2': {
userId: 2,
bugs: some([]),
},
'3': {
userId: 3,
bugs: some([
{
bugId: 1,
description: none,
},
]),
},
},
};
console.log('\n\nFirst Test\n\n');
console.log('getUser1', getUserO(1).getOption(state));
console.log('getUser2', getUserO(2).getOption(state));
console.log('getUser3', getUserO(3).getOption(state));
console.log('getUser4', getUserO(4).getOption(state));
console.log('\n\nSecond Test\n\n');
console.log(
'modifyBug1.1',
getBugT(1, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log(
'modifyBug2.1',
getBugT(2, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log(
'modifyBug3.1',
getBugT(3, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log('\n\nThird Test\n\n');
console.log(
'LPT: modifyBug1.1',
getBugLTP(1, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log(
'LPT: modifyBug2.1',
getBugLTP(2, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log(
'LPT: modifyBug3.1',
getBugLTP(3, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log('\n\nFourth Test\n\n');
console.log(
'O: modifyBug1.1',
getBugO(1, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log(
'O: modifyBug2.1',
getBugO(2, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log(
'O: modifyBug3.1',
getBugO(3, 1).modify(b => ({ ...b, description: some('Har') }))(state)
);
console.log('\n\nFifth Test\n\n');
console.log('getBug1.1', getBugO(1, 1).getOption(state));
console.log('getBug2.1', getBugO(2, 1).getOption(state));
console.log('getBug3.1', getBugO(3, 1).getOption(state));
console.log(
'modify3.1',
getBugO(3, 1).modify(b => ({ ...b, description: some('Hello') }))(state)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment