• [Functional Programming] Combine State Dependent Transactions with the State ADT (composeK to replace multi chian call)


    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
        )
    )*/
  • 相关阅读:
    pat 乙级1084 外观数列
    将int 转换为string 函数 to_string()
    stl find_first_not_of()函数
    小写转变为大写函数toupper()
    基础实验2-2.3 组合数的和 (15分)
    基础实验2-2.2 求集合数据的均方差 (15分)
    习题1.9 有序数组的插入 (20分)
    用eclipse运行算法第四版的BinarySearch
    关于脱发
    HUD-2586(LCA板子)
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10235148.html
Copyright © 2020-2023  润新知