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. RabbitMQ基础命令rabbitmqctl

    官网文档 https://www.rabbitmq.com/rabbitmqctl.8.html 一般操作命令后台管理页面都有的,部分没有(应用程序管理,和集群管理). 直接使用命令,必须配置环境变量 ...

  2. python学习-53 正则表达式

    正则表达式 就其本质而言,正则表达式是一种小型的/高度专业化的编程语言,它内嵌在python中,并通过RE模块实现,正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行. 1.元字符 - ...

  3. C++进行字母大小写转换

    #include <iostream> #include <Windows.h> #include <string> using namespace std; in ...

  4. 计算机网络自顶向下方法第3章-传输层 (Transport Layer).2

    3.5 面向连接的运输: TCP 3.5.1 TCP连接 TCP是因特网运输层的面向连接的可靠的运输协议. TCP连接提供全双工服务(full-duplex service). TCP连接是点对点的连 ...

  5. 【并发】9、借助redis 实现生产消费,消息订阅发布模式队列

    这个就是一个消息可以被多次消费的范例了 其实这个实现的方式可以参考我之前的设计模式,观察者模式 https://www.cnblogs.com/cutter-point/p/5249780.html ...

  6. AS3.0 位图翻转、旋转

    /* * * *-------------------------* * | *** 位图翻转.旋转 *** | * *-------------------------* * * 作 者:fengz ...

  7. 1byte、1KB、4KB,1MB、1GB用16进制表示的范围。任意地址范围求字节数

    1byte.1KB.4KB,1MB.1GB用16进制表示的范围.任意地址范围求字节数 2018-02-12 18:27:48 望那伊人 阅读数 5032更多 分类专栏: 计算机相关   版权声明:本文 ...

  8. 撸一个 vue 的截图组件,按比例截取

    <template> <div class="clip-img" :style="imgStyle"> <img :src=&qu ...

  9. 1.VBA Excel宏

    Excel VBA宏 在这一章中,让我们了解如何编写一个简单的宏.让我们一步一步来. 第1步:首先,让我们能够在Excel20XX'开发'菜单.做同样的,点击 File >> Option ...

  10. 在论坛中出现的比较难的sql问题:40(子查询 销售和历史库存)

    原文:在论坛中出现的比较难的sql问题:40(子查询 销售和历史库存) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有 ...