[Functional Programming ADT] Adapt Redux Actions/Reducers for Use with the State ADT
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的更多相关文章
- [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 ...
- [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 ...
- Beginning Scala study note(4) Functional Programming in Scala
1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...
- [Functional Programming ADT] Combine Multiple State ADT Based Redux Reducers
Redux provides a convenient helper for combining many reducers called combineReducer, but it focuses ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
随机推荐
- 【转载】Banner框架
原文地址:https://github.com/youth5201314/banner 以前banner都自己写,又丑问题又多,在github上找到一个点赞最多的,动画效果那是绚丽多彩啊,好东东当然要 ...
- 590. N叉树的后序遍历
给定一个 N 叉树,返回其节点值的后序遍历. 例如,给定一个 3叉树 : 返回其后序遍历: [5,6,3,2,4,1]. 说明: 递归法很简单,你可以使用迭代法完成此题吗? /* // Definit ...
- HashMap底层数据结构和算法解析
1.Hash Map的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点.当链表长度超过8时,链表转换为红黑树. transient Node<K,V>[] ta ...
- 笔试之random7生成random10
/*头条 已知有个Random7()的函数,返回1到7随机自然数,让利用这个Random7()构造Random10()随机1~10. random7构造1~49,限制到1~40,对10求余再+1 */ ...
- 每日一刷(2018多校水题+2016icpc水题)
11.9 线段树 http://acm.hdu.edu.cn/showproblem.php?pid=6315 求逆序对个数 http://acm.hdu.edu.cn/showproblem.php ...
- oracle return code 2112
SQL-02112 SELECT..INTO returns too many rows Cause: A SELECT...INTO statement returned more rows tha ...
- android studio安卓工作室 工具栏
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha android studio安卓工作室 工具栏 都有什么 . 打开.保存全部.刷新.撤 ...
- Spring 概念详解
一.Spring的IoC(Inversion of Control). 这是Spring中得有特点的一部份.IoC又被翻译成“控制反转”,也不知道是谁翻译得这么别扭,感觉很深奥的词.其实,原理很简单, ...
- 【POJ 2154】Color
http://poj.org/problem?id=2154 还是先套上Burnside引理:\[\begin{aligned} ans & =\sum_{i=1}^n n^{(i,n)-1} ...
- 【BZOJ 4104】【THUSC 2015】解密运算
http://www.lydsy.com/JudgeOnline/problem.php?id=4104 网上题解满天飞,我也懒得写了 #include<cstdio> #include& ...