zoukankan      html  css  js  c++  java
  • [Functional Programming] Using ComposeK for both get State and modify State

    We have State like this:

    const state = {
      cards: [
        { id: "green-square", color: "green", shape: "square" },
        { id: "orange-square", color: "orange", shape: "square" },
        { id: "blue-triangle", color: "blue", shape: "triangle" }
      ],
      hint: {
        color: "green",
        shape: "square"
      },
      isCorrect: null,
    };

    We want to validate user's input is the same as 'hint' and it matchs 'id' in cards array. Then we want to set 'isCorrect' to 'false' or 'true'.

    In this flow, we want to do two things:

    1. Able to set state, which is 'isCorrect'
    2. Able to get multi states, 'cards', 'hint', and validate they are matched
    3. In the end, we need to get the result from Step 2 to set value in Step 1

    In this kind of flow, we can use 'composeK' all the way down.

    Able to set state:

    // over :: (String, (a -> b)) -> Object -> State Object ()
    const over = (key, fn) => modify(mapProps({ [key]: fn }));
    // setIsCorrect :: Boolean -> State AppState () const setIsCorrect = isCorrect => over("isCorrect", constant(isCorrect));

    Able to get multi state:

    // getState :: String -> State Object (Maybe a)
    const getState = key => get(prop(key));
    
    // Hint :: {color: String, shape: String}
    // Card :: {id: String, color: String, shape: String}
    
    // getHint :: () -> State AppState Hint
    const getHint = () =>
      getState("hint").map(option({ color: "unknown", shape: "unknown" }));
    
    // getCard :: String -> State AppState Card
    const getCard = id =>
      getState("cards")
        .map(chain(find(propEq("id", id))))
        .map(option({ id, color: "unknown", shape: "unknown" }));

    Able to validate:

    // liftState :: (a -> b) -> a -> State s b
    const liftState = fn =>
      compose(
        State.of,
        fn
      );
    
    // cardToHint :: Card -> State AppState Hint
    const cardToHint = composeK(
      liftState(omit(["id"])),
      getCard
    );
    
    // validateAnswer :: String -> State AppState Boolean
    const validateAnswer = converge(liftA2(equals), cardToHint, getHint);

    Do both Get and Set state:

    const feedback = composeK(
      setIsCorrect,
      validateAnswer
    );

    ---

    const state = {
      cards: [
        { id: "green-square", color: "green", shape: "square" },
        { id: "orange-square", color: "orange", shape: "square" },
        { id: "blue-triangle", color: "blue", shape: "triangle" }
      ],
      hint: {
        color: "green",
        shape: "square"
      },
      isCorrect: null,
      left: 8,
      moves: 0
    };
    
    log(feedback("green-square").execWith(state));
  • 相关阅读:
    iOS网络编程开发-数据加密
    iOS网络编程开发GET请求和POST请求
    iOS网络编程开发—HTTP协议
    iOS网络编程开发—网络编程基础
    iOS多线程技术—自定义NSOperation
    iOS多线程技术—NSOperation用法
    大家一起和snailren学java-(一)对象导论
    大家一起和snailren学java-(序)
    Hadoop 2.7.0模拟分布式实验环境搭建[亲测]
    LeetCode:103Binary Tree Zigzag Level Order Traversal
  • 原文地址:https://www.cnblogs.com/Answer1215/p/11156862.html
Copyright © 2011-2022 走看看