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的更多相关文章

  1. 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 ...

  2. [Functional Programming] Using ComposeK for both get State and modify State

    We have State like this: const state = { cards: [ { id: "green-square", color: "green ...

  3. [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 ...

  4. [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 ...

  5. [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 ...

  6. [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 ...

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

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

  8. [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 ...

  9. [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 ...

随机推荐

  1. php中array_replace,array_splice和str_replace三个函数相互比较

    php中有一些功能相似或者是名称相似的函数,比如array_replace,array_splice和str_replace这三个函数,从名称来看前两个操作数组的,后一个操作字符串的. array_r ...

  2. Linux基础-09-磁盘分区、挂载及文件系统管理

    1. 硬件设备与文件名的对应关系 1) 在Linux系统中,每个设备都被当初一个文件来对待. 2) 各种设备在Linux中的文件名 2. 硬盘的结构及硬盘分区 1) 为什么要进行硬盘分区: a) 更容 ...

  3. django使用pyecharts(5)----django加入echarts_增量更新_定长

    五.Django 前后端分离_定时增量更新图表定长数据 1.安装 djangorestframework linux pip3 install djangorestframework windows ...

  4. Cow Brainiacs

    #include<stdio.h> int main() { ,i; scanf("%d %d",&n,&b); ;i<=n;i++) { f*= ...

  5. golang开发:环境篇(五)实时加载工具gin的使用

    gin 工具是golang开发中非常有用且有效的工具,有效的提高了开发调试go程序的效率. 为什么要使用gin 我们知道golang是编译型语言,这就表示go程序的每次改动,如果需要查看改动结果都必须 ...

  6. my linux cmd

    常用的linux命令 一.vi yy 复制当前行 u 撤销 p 粘贴 dd 删除当前行 set nu 显示行号 gg 首行 G 末行 二.用户管理相关 useradd 添加用户   (默认创建一个与用 ...

  7. javascript 之 call,apply原理

    一.call原理 1.使用JQuery的call功能 var add(c,d){ return this.a+this.b+c+d } var obj={a:1,b:2} add.Call(obj,3 ...

  8. POJ3368(Frequent values)--线段树

    题目在这里 3368 Accepted 7312K 1829MS C++ 6936B 题意为给你一组数据,再给定一组区间,问你这个区间内出现次数最多的元素的次数是多少. 我还记得这题是学校校赛基础的题 ...

  9. 六、eureka客户端自动注册服务

    所有文章 https://www.cnblogs.com/lay2017/p/11908715.html 正文 上一篇文章,我们稍微了解了一下eureka客户端是如何自动配置的,配置了哪些东西.在自动 ...

  10. iOS - Scenekit3D引擎初探之 - 导出DAE文件(3Dmax为例)

    DAE文件格式是3D交互文件格式,一般用于多个图形程序之间交换数字数据,Autodesk专有并在COLLADA(COLLAborative Design Activity)基础上改进创建的XML框架的 ...