[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 ...
随机推荐
- idea使用maven+Tomcat
1.创建maven项目,并使用webapp骨架,并修改pom.xml文件 <build> <finalName>myWebApp</finalName> <! ...
- ~jmeter解决csrftoken登录问题
一.登录接口 url:http://192.168.163.128:/user/login/ 请求方法:post 请求参数: account:用户名 password:登录密码 remember:是否 ...
- 从零开始学Flask框架-003
index.py from flask import Flask,render_template from flask_bootstrap import Bootstrap #初始化 app = Fl ...
- Python进阶:值传递,引用传递?不存在的,是赋值传递
Python的变量及其赋值 c/c++/c#/java 里面都有值传递,引用传递的概念,在Python中是如何的? 例 a = 1 b = a print(id(a),id(b)) #14072334 ...
- pod宿主机挂载pv存储过程
1处的控制循环Control Loop应该是:VolumeManagerReconciler ----------------------------------------------------- ...
- C++标识符的作用域与可见性
一.标识符的作用域与可见性 作用域讨论的是标识符的有效范围,可见性讨论的是标识符是否可以被引用. 二.作用域 作用域是一个标识符在程序正文中有效的区域.C++中标识符的作用域有函数原型作用域.局部作用 ...
- [A]System.Web.WebPages.Razor.Configuration.HostSection 无法强制转换为 [B]解决办法
- Bigdecimal除法异常
1.异常信息摘要(详细请见文末): java.lang.ArithmeticException: Non-terminating decimal expansion; no exact represe ...
- java线程的五种状态
五种状态 开始状态(new) 就绪状态(runnable) 运行状态(running) 阻塞状态(blocked) 结束状态(dead) 状态变化 1.线程刚创建时,是new状态 2.线程调用了sta ...
- PL/SQL Developer_如何快速获得表名或全部列名的文本形式
转自:https://blog.csdn.net/xwnxwn/article/details/53388887 操作过程: 例1:以“逗号”格式获取“用户表名”的文本 使用scott登陆到PL/SQ ...