As a beginner of Crocks.js, it was a problem for we to figure out when to use .map() and when to use .chain().
Of course, using the docs help:
map: State s a ~> (a -> b) -> State s b
chain: State s a ~> (a -> State s b) -> State s b
The main difference is that, when using .map(fn), the param is a function.
For exmaple: addOne is just a plain function.
const addOne = x => x + 1;
When using .chian(sfn), the param is a State(fn)
For example: modify return a state() and inside state(), we apply function addOne.
const modifyOne = () => modify(mapProps({'moves', addOne}));
Now, we are going to write two example, one is using .map() another one is using .chain() to achieve the same result.
// We want to get final result as {moves: 4} const state = { moves: 1 }
.chain():
const { curry, compose, State, mapProps, prop, option } = require("crocks"); const { modify, get } = State; const getState = key => get(prop(key)); const addOne = x => x + 1; const modifyOne = () => over('moves', addOne); const over = (key, fn) => modify(mapProps({[key]: fn})) const state = { moves: 1 } const getMoves = () => getState('moves').map(option(0)) console.log( getMoves() .chain(modifyOne) .chain(modifyOne) .chain(modifyOne) .execWith(state) // {moves: 4} )
Notice that 'getMoves' and 'modifyOne' both return State(), so they have to use .chian().
.map():
const { curry, compose, State, mapProps, prop, option } = require("crocks"); const { modify, get } = State; const getState = key => get(prop(key)); const addOne = x => x + 1; const state = { moves: 1 } const getMoves = () => getState('moves').map(option(0)) console.log( getMoves() .map(addOne) .map(addOne) .map(addOne) .evalWith(state) // 4 )
Since 'addOne' is just a function, we can use .map() instead of .chian(). And more important, we have to use 'evalWith' to get result value, since we are not using 'modify' to change the state.