When developing a Finite State Machine, it is often necessary to apply multiple transitions in tandem. To accomplish this in most Redux work flows requires at best, implementing multiple action handlers in separate reducers; or at worse, the need to duplicate logic for similar action handlers, sometime across multiple files. However when using a State ADT, we can easily combine these independent transitions by simply chain-ing multiple discrete transitions into one transaction. We demonstrate this interface by transitioning two portions of related state with one transaction.

const { curry, compose, State, mapProps, composeK } = require("crocks");

const { modify } = State;

const state = {
left: 8,
moves: 0
}; const inc = x => x + 1;
const dec = x => x - 1; const clamp = (min, max) => x => Math.min(Math.max(min, x), max);
const clampAfter = curry((min, max, fn) =>
compose(
clamp(min, max),
fn
)
);
const over = (key, fn) => modify(mapProps({ [key]: fn })); const limitMoves = clampAfter(0, 8); const decLeft = () => over("left", limitMoves(dec));
const incMoves = () => over("moves", limitMoves(inc)); // Then there are a series of chain functions, using composeK
/**
* replace:
* decLeft()
* .chain(decLeft)
* .chain(decLeft)
* .chain(decLeft)
* .chain(incMoves)
* .chain(incMoves)
*/
const applyMove = composeK(
incMoves, incMoves, decLeft, decLeft, decLeft
) const res = applyMove()
.execWith(state);
console.log(res); //{ left: 5, moves: 2 }

Another example:

const state = {
cards: [
{id: 'green-square', color: 'green', shape: 'square'},
{id: 'orange-square', color: 'orange', shape: 'square'},
{id: 'blue-square', color: 'blue', shape: 'triangle'}
],
left: 8,
moves: 0
} const {State, when, assign, map, mapProps, propEq} = require('crocks');
const {modify} = State; const markSelected = id => assignBy(propEq('id', id), {selected: true})
const assignBy = (pred, obj) => when(pred, assign(obj));
const over = (key, fn) => modify(mapProps({ [key]: fn })); const selectCard = id => over('cards', map(markSelected(id))) console.log(
JSON.stringify(
selectCard('green-square').execWith(state),
null,
2
)
); /*
// Using Ramda to implememnt the same logic
const {compose, map, propOr, when, propEq, mergeLeft} = require('ramda'); const markAsSelected = (id) => when(propEq('id', id), mergeLeft({selected: true}))
const over = (key, fn) => compose(map(fn), propOr([], key)); const selectCard2 = (id) => over('cards', markAsSelected(id)) console.log(
JSON.stringify(
selectCard2('green-square')(state),
null,
2
)
)*/

[Functional Programming] Combine State Dependent Transactions with the State ADT (composeK to replace multi chian call)的更多相关文章

  1. [Functional Programming] Read and Transform Values from a State ADT’s State (get)

    Many times we need to access and transform state, either in part or in full, to be used when calcula ...

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

  3. [Functional Programming Monad] Combine Stateful Computations Using Composition

    We explore a means to represent the combination of our stateful computations using familiar composit ...

  4. [Functional Programming Monad] Modify The State Of A State Monad

    Using put to update our state for a given state transaction can make it difficult to modify a given ...

  5. [Functional Programming Monad] Map And Evaluate State With A Stateful Monad

    We explore our first stateful transaction, by devising a means to echo our state value into the resu ...

  6. [Functional Programming] Introduction to State, thinking in State

    Recently, I am learning Working with ADT. Got some extra thought about State Monad. Basiclly how to ...

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

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

  9. [Functional Programming] Rewrite a reducer with functional state ADT

    For example we have a feature reducer like this: // selectCard :: String -> Action String export ...

随机推荐

  1. Codeforces 934.A A Compatible Pair

    A. A Compatible Pair time limit per test 1 second memory limit per test 256 megabytes input standard ...

  2. 简易web服务器(npm)

    npm install -g http-server 以后可以在任何一个文件夹启动静态文件的访问通过http-server -a localhost -p 8000ctrl + c结束 http-se ...

  3. python面试经典315

    期待的是可以检验自己学习的成功:苦逼的是怎么又有东西没记住,但我们依然每天坚持一遍.一遍又一遍指导记住为止. 第一部分 Python基础篇(80题) 为什么学习Python? 通过什么途径学习的Pyt ...

  4. 全自动google检索后台

    是不是每天为了找后台,伤破了蛋,每次在google输入”site:www.xxx.com intitle:登陆”.是不是手都累麻了,无聊又浪费时间.有了它,你的蛋就不用在碎了 直接上源码 1 2 3 ...

  5. 寻找道路(NOIP2014)神奇之题。。

    原题传送门 这道题嘛.. 首先根据题目,我们要先知道哪些点能够到达终点.(反向BFS) 然后我们再求最短路的途中,必须随时判断周围的点是否被第一次BFS标记过.. 所以再来一次BFS. 数组记得清零, ...

  6. urb数据结构【转】

    转自:http://blog.csdn.net/myarrow/article/details/7025065 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 一 transf ...

  7. ros navigation stack---move_base

    大部分内容参考自: ros_by_example_hydro_volume_1.pdf 主要是讲如何让先锋机器人在空白地图上运动 上面图是navigation框架图,可以看到move_base处在核心 ...

  8. IIS——MIME介绍与添加MIME类型

    MIME(MultipurposeInternet Mail Extensions)多用途互联网邮件扩展类型.是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会 ...

  9. JDK7集合框架源码阅读(五) Hashtable

    基于版本jdk1.7.0_80 java.util.Hashtable 代码如下 /* * Copyright (c) 1994, 2011, Oracle and/or its affiliates ...

  10. (1)请求web

    用来测试api的例子 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...