[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 ...
随机推荐
- kafka 集群环境搭建 java
简单记录下kafka集群环境搭建过程, 用来做备忘录 安装 第一步: 点击官网下载地址 http://kafka.apache.org/downloads.html 下载最新安装包 第二步: 解压 t ...
- csdn博客整理
@TOC 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页.如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown ...
- 图像处理库 Pillow与PIL
PIL只支持python2的版本到2.7: Python imaging Library : Pillow 是PIL派生的一个分支,支持3以上Python版本. 命令使用pip安装: pip inst ...
- Django项目配置参数大全
数据库的配置 配置文件: settings.pyDATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NA ...
- 计算机网络自顶向下方法第3章-传输层 (Transport Layer).2
3.5 面向连接的运输: TCP 3.5.1 TCP连接 TCP是因特网运输层的面向连接的可靠的运输协议. TCP连接提供全双工服务(full-duplex service). TCP连接是点对点的连 ...
- PAT(B) 1084 外观数列(Java)
题目链接:1084 外观数列 (20 point(s)) 题目描述 外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, - 它从不等于 ...
- docker 实践七:docker-machine
本篇是关于 docker 三剑客中的 docker machine. 注:环境为 CentOS7,docker 19.03. docker-machine 是 docker 官方三剑客项目之一,它是一 ...
- git彻底删除或变更子模块
今天遇到一个很怪的问题,我想把我的一个子模块切换到另一个上游,我按照网上的方法删除子模块然后新建后,这个子模块依旧跟踪着我先前的上游.自己摸索了一下,可能方法比较傻,不过是可行的,希望能给大家一些帮助 ...
- Scratch 少儿编程之旅(四)— Scratch入门动画《小猫捉蝴蝶》(中)
本期内容概括: 了解Scratch的更多操作,用[无限循环]来更改“小猫”角色的代码: 添加[碰到边缘就反弹]积木块指令: 更改角色的旋转模式和造型,让”小猫”走路更生动: 两种[循环]语句的区别: ...
- 2.33模型--去除字符串两头空格.c
[注:本程序验证是使用vs2013版] #include <stdio.h> #include <stdlib.h> #include <string.h> #pr ...