[Functional Programming] Combine Multiple State ADT Instances with the Same Input (converge(liftA2(constant)))
The with input State Programming multiple functional same
2023-09-14 08:59:15 时间
When combining multiple State
ADT instances that depend on the same input, using chain
can become quite burdensome. We end up having to play leapfrog with values inside of nested chain statements. Very reminiscent of the old callback nastiness we had to deal with before Promises
graced our existence.
But fear not, but taking advantage of the Applicative Functor portion of the State
ADT in combination with the converge
combinator, we can apply these types of transitions in unison, passing the value to both virtually simultaneously.
For example:
// () -> b const validateAnswer = converge( liftA2(equals), cardToHint, getHint )
'validateAnswer' return a boolean value.
We want to take this value, and pass to two functions 'setIsCorrect' & 'updateRank'
// b -> () const setIsCorrect = b => over('isCorrect', constant(b)); // b -> () const updateRank = b => over('rank', adjustRank(b));
One functional way to do this is using 'converge':
const applyFeedback = converge( liftA2(constant), setIsCorrect, updateRank )
----------------
const {prop, State, omit, curry, converge,map, composeK, liftA2, equals, constant,option, chain, mapProps, find, propEq, isNumber, compose, safe} = require('crocks'); const {get, modify, of} = State; const state = { cards: [ {id: 'green-square', color: 'green', shape: 'square'}, {id: 'orange-square', color: 'orange', shape: 'square'}, {id: 'blue-triangle', color: 'blue', shape: 'triangle'} ], hint: { color: 'green', shape: 'square' }, isCorrect: null, rank: 2 } const inc = x => x + 1; const dec = x => x - 1; const incOrDec = b => b ? dec : inc; const clamp = (min, max) => x => Math.min(Math.max(min, x), max); const clampAfter = curry((min, max, fn) => compose(clamp(min, max), fn)); const limitRank = clampAfter(0, 4); const over = (key, fn) => modify(mapProps({[key]: fn})) const getState = key => get(prop(key)); const liftState = fn => compose( of, fn ) const getCard = id => getState('cards') .map(chain(find(propEq('id', id)))) .map(option({})) const getHint = () => getState('hint') .map(option({})) const cardToHint = composeK( liftState(omit(['id'])), getCard ) // () -> b const validateAnswer = converge( liftA2(equals), cardToHint, getHint ) // b -> () const setIsCorrect = b => over('isCorrect', constant(b)); const adjustRank = compose(limitRank, incOrDec); // b -> () const updateRank = b => over('rank', adjustRank(b)); const applyFeedback = converge( liftA2(constant), setIsCorrect, updateRank ) const feedback = composeK( applyFeedback, validateAnswer ) console.log( feedback('green-square') .execWith(state) )
相关文章
- Android问题-No resource found that matches the given name (at 'theme' with value '@style/CaptureTheme').
- [Typescript] Extract the Discriminator from a Discriminated Union
- [AWS] Lab: Configure and Work with CodeCommit from the CLI
- [Jest] Restore the Original Implementation of a Mocked JavaScript Function with jest.spyOn
- 【资料整理】Security Features in the CRT
- [Functional Programming] Combine Multiple State ADT Instances with the Same Input (converge(liftA2(constant)))
- [AngularJS] Using an AngularJS directive to hide the keyboard on submit
- There is no source code available for the current location
- Custom tool error: Failed to generate code for the service reference ××××××. Please check other erro
- 【Codeforces 1083A】The Fair Nut and the Best Path
- Unexpected XML declaration. The XML declaration must be the first node in the document and no white
- Matlab:成功解决Function definition are not permitted at the prompt or scripts
- 成功解决The following specifications were found to be incompatible with the existing python installation
- 2022亚太E题——How Many Nuclear Bombs can Destroy the Earth?(思路、程序)
- The current user does not have write permissions to the target environment.
- KASH-The Secret Of Excellence
- No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'
- clang编译kernel4.9报错:the compat vDSO will not be built
- HDU 1599 find the mincost route
- Your configuration specifies to merge with the ref