By using the State ADT to define how our application state transitions over time, we clear up the need for a some of the boilerplate that we typically need for a solid Redux integration. We can keep our action names and creators in the same file as the reducer they are used in, as we no longer need to have separate files to hand the same action across different portions of our state.

We will build our a single reducer that will handle the integration with Redux and organize our State ADT based reducers in their own files and bring them into our main reducer to handle running our state transitions and the cases where we do not have an transition for a given action.

// Action a :: {type: string, payload: a}
// createAction :: String -> a -> Action a
const createAction = type => payload => ({type, payload});
const SELECT_CARD = 'SELECT_CARD';
const selectCard = createAction(SELECT_CARD); // reducer :: (State, a) -> (State AppState ()) | Null
const reducer = (prevState, {type, payload}) => {
let result;
switch(type) {
case SELECT_CARD:
result = feedback(payload);
break;
default:
result = null;
} return isSameType(State, result) ? result.execWith(prevState): prevState;
} const sillyVerb = createAction('SILLY_VERB'); console.log(
reducer(
state,
selectCard('green-square')
)
)

If we pass the right action, it will return the result, if a bad action, it keep the prev state untouched.

---

const {prop, isSameType, 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
)
const validateAnswer = converge(
liftA2(equals),
cardToHint,
getHint
)
const setIsCorrect = b => over('isCorrect', constant(b));
const adjustRank = compose(limitRank, incOrDec);
const updateRank = b => over('rank', adjustRank(b));
const applyFeedback = converge(
liftA2(constant),
setIsCorrect,
updateRank
)
const feedback = composeK(
applyFeedback,
validateAnswer
)
// Action a :: {type: string, payload: a}
// createAction :: String -> a -> Action a
const createAction = type => payload => ({type, payload});
const SELECT_CARD = 'SELECT_CARD';
const selectCard = createAction(SELECT_CARD); // reducer :: (State, a) -> (State AppState ()) | Null
const reducer = (prevState, {type, payload}) => {
let result;
switch(type) {
case SELECT_CARD:
result = feedback(payload);
break;
default:
result = null;
} return isSameType(State, result) ? result.execWith(prevState): prevState;
} const sillyVerb = createAction('SILLY_VERB'); console.log(
reducer(
state,
selectCard('green-square')
)
)

[Functional Programming ADT] Adapt Redux Actions/Reducers for Use with the State ADT的更多相关文章

  1. [Functional Programming] Randomly Pull an Item from an Array with the State ADT (Pair)

    Functor composition is a powerful concept that arises when we have one Functor nested in another Fun ...

  2. [React + Functional Programming ADT] Connect State ADT Based Redux Actions to a React Application

    With our Redux implementation lousy with State ADT based reducers, it is time to hook it all up to a ...

  3. Beginning Scala study note(4) Functional Programming in Scala

    1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...

  4. [Functional Programming ADT] Combine Multiple State ADT Based Redux Reducers

    Redux provides a convenient helper for combining many reducers called combineReducer, but it focuses ...

  5. [Functional Programming ADT] Create a Redux Store for Use with a State ADT Based Reducer

    With a well defined demarcation point between Redux and our State ADT based model, hooking up to a R ...

  6. [Functional Programming ADT] Create State ADT Based Reducers (applyTo, Maybe)

    The typical Redux Reducer is function that takes in the previous state and an action and uses a swit ...

  7. [Functional Programming ADT] Initialize Redux Application State Using The State ADT

    Not only will we need to give our initial state to a Redux store, we will also need to be able to re ...

  8. [Functional Programming] Combine State Dependent Transactions with the State ADT (composeK to replace multi chian call)

    When developing a Finite State Machine, it is often necessary to apply multiple transitions in tande ...

  9. [Functional Programming] Combine Multiple State ADT Instances with the Same Input (converge(liftA2(constant)))

    When combining multiple State ADT instances that depend on the same input, using chain can become qu ...

随机推荐

  1. win10的VMware虚机host-only模式下,虚拟机无法ping通物理机,而物理机能ping通虚机

    1.打开控制面板—->Windows防火墙(win10操作系统) 2.点击最上面的”允许应用或功能通过xxxxx” 3.勾上上图的“文件和打印机共享” 然后点确定.

  2. windows安装elasticsearch和elasticsearch-head插件

    1.去官网下载最新软件 选择zip包,https://www.elastic.co/downloads/elasticsearch 2.下载node 必须 > 6.0已上 3.解压elastic ...

  3. 04、Unity_声音管理器

    1.分享一个Unity中用于管理声音的声音管理器,适合于中小型项目,大项目就算了. 2.借鉴了很多的源码,最后修改完成,吸取百家之长,改为自己所用,哈哈. 3.源码奉上: /* * * 开发时间:20 ...

  4. oracle return code 2112

    SQL-02112 SELECT..INTO returns too many rows Cause: A SELECT...INTO statement returned more rows tha ...

  5. Redux 洋葱模型理解

    下面的代码会输出: A middleware1 开始C middleware2 开始E middleware3 开始======= G =======F middleware3 结束D middlew ...

  6. JZYZOJ1502 [haoi2008]下落的圆盘 计算几何 贪心

    http://172.20.6.3/Problem_Show.asp?id=1502这种题用了快一天才写出来也是真的辣鸡.主要思路就是计算一下被挡住的弧度然后对弧度进行贪心.最开始比较困扰的是求弧度值 ...

  7. xcoj 1103 插线板(树链刨分求最大子段和)

    1103: 插线板 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...

  8. code M资格赛 补题

    A: 音乐研究 时间限制:1秒 空间限制:32768K 美团外卖的品牌代言人袋鼠先生最近正在进行音乐研究.他有两段音频,每段音频是一个表示音高的序列.现在袋鼠先生想要在第二段音频中找出与第一段音频最相 ...

  9. 【二分】Subsequence

    [POJ3061]Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15908   Accepted:  ...

  10. 【主席树】Gym - 101237A - MEX-Query

    主席树里每个值的位置存当前该值出现的最右位置. 如果root[r]的前缀主席树中,某值最右位置大于等于l,说明该值出现在了l,r中. 所以主席树维护区间最小值,如果左半值域的最小值<l,则说明左 ...