zoukankan      html  css  js  c++  java
  • [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
        )
    )*/
  • 相关阅读:
    git ——visual studio code 工具之 Git Graph & git clone & git checkout
    docker中添加redis & 在程序中应用
    Configuring Redis for ASP.NET Core Session Store(转载)
    Configuring Redis Session State In ASP.NET Core(转载)
    http请求端口占用异常——处理思路
    在pods中添加有关httpclient的 压力测试 & 监控
    Singleton HttpClient? Beware of this serious behaviour and how to fix it
    HttpClient 之 CLOSE_WAIT
    HttpClient的使用
    HttpClient连接池之CLOSE_WAIT
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10235148.html
Copyright © 2011-2022 走看看