[Functional Programming] Rewrite a reducer with functional state ADT
For example we have a feature reducer like this:
// selectCard :: String -> Action String
export const selectCard =
createAction(SELECT_CARD) // showFeedback :: String -> Action String
export const showFeedback =
createAction(SHOW_FEEDBACK) // reducer :: Action a -> (State AppState ()) | Null
const reducer = ({ type, payload }) => {
switch (type) {
case SELECT_CARD:
return answer(payload) case SHOW_FEEDBACK:
return feedback(payload)
} return null
} export default reducer
First of all, we can replace 'swtich' statement with normal Object:
const actionReducer = {
SELECT_CARD: answer,
SHOW_FEEDBACK: feedback
}
// reducer :: Action a -> (State AppState ()) | Null
const reducer = ({ type, payload }) => (actionReducer[type] || Function.prototype)(payload)
In case of ´actionReducer[type]´ return undefined, we default a function by `Function.prototype`, ready to take a payload.
const reducer = ({ type, payload }) => (actionReducer[type] || Function.prototype)(payload)
This type of code is suitable for using 'Maybe'.
// createReducer :: ActionReducer -> Reducer
export const createReducer = actionReducer =>
({ type, payload }) =>
prop(type, actionReducer)
.map(applyTo(payload))
Refactor:
// showFeedback :: String -> Action String
export const showFeedback =
createAction(SHOW_FEEDBACK) const reducer = createReducer({
SELECT_CARD: answer,
SHOW_FEEDBACK: feedback
}) // reducer :: Action a -> (State AppState ()) | Null
// const reducer = ({ type, payload }) =>
// (actionReducer[type] || Function.prototype)(payload) export default reducer
For this workflow, the following code should also be chagned to handle Maybe type:
// From
import turn from './turn' //reducer :: (AppState, Action a) -> AppState
const reducer = (prev, action) =>
const result = turn(action) return isSameType(State, result)
? result.execWith(prev)
: prev
} export default reducer // To
import turn from './turn' //reducer :: (AppState, Action a) -> AppState
const reducer = (prev, action) =>
turn(action)
.chain(safe(isSameType(State)))
// ? result.execWith(prev)
// : prev export default reducer
Here ´turn(action)´ return a Maybe type, we still need to check whether inside Maybe, it is `State` type,
.chain(safe(isSameType(State)))
If it is, then we call `execWith` otherwise we return previous state:
const reducer = (prev, action) =>
turn(action)
.chain(safe(isSameType(State)))
.map(execWith(prev))
.option(prev)
[Functional Programming] Rewrite a reducer with functional state ADT的更多相关文章
- Functional Programming without Lambda - Part 1 Functional Composition
Functions in Java Prior to the introduction of Lambda Expressions feature in version 8, Java had lon ...
- [Functional Programming] Using ComposeK for both get State and modify State
We have State like this: const state = { cards: [ { id: "green-square", color: "green ...
- [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] 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 ...
- [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 ...
- [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 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 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] 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 ne ...
随机推荐
- centos 安装notepad++
notepad++在linux下名字为notepadqq第一步,还是下载软件库$ sudo wget -O /etc/yum.repos.d/sea-devel.repo http://sea.fed ...
- Linux大道——博客目录
Linux基础 第一章 计算机基础 计算机基础 网络基础 第二章 Linux基础
- 关于python的一次性能调优过程
问题 这两天在公司帮老大写一个程序功能,要求抓取从elasticsearch和kibana服务器上返回的数据,统计所有hits的数据字段ret_code为0的hit,并计算其占有率等一些功能. 功能倒 ...
- Python进阶:并发编程之Futures
区分并发和并行 并发(Concurrency). 由于Python 的解释器并不是线程安全的,为了解决由此带来的 race condition 等问题,Python 便引入了全局解释器锁,也就是同一时 ...
- Bad owner or permissions on .ssh/config win10问题解决
最近向系统添加了新用户账号后出现了问题,尝试使用私钥登陆服务器,提示了 Bad owner or permissions on .ssh/config 这个报错,就是如题中的问题 修复 按照Windo ...
- mysql 系统变量
show variables; ---------------------------------+-------------------------------------------------- ...
- R_数据视觉化处理_中阶_05
条形图:条形图通过垂直或水平的条形展示了类型变量的分布(频数).最简单的用法为:barplot(height),height为矩阵或向量. horiz=TRUE选项:表示水平,在此之前先使用table ...
- Windows下编译 Hadoop
Windows下编译 Hadoop-2.9.2 系统环境 系统: Windows 10 10.0_x64 maven: Apache Maven 3.6.0 jdk: jdk_1.8.0_201 Pr ...
- js 单线程 异步
线程与进程: 进程是系统资源分配和调度的单元.一个运行着的程序就对应一个进程.在windows中,每一个打开的运行的应用程序或后台程序,比如运行中的qq,谷歌浏览器,网易云音乐,资源管理器等都是一个进 ...
- CSS_引入方式
一 CSS的引入方式 CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离 1.行内式 ...