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: ,
moves:
}; log(feedback("green-square").execWith(state));

[Functional Programming] Using ComposeK for both get State and modify State的更多相关文章

  1. [Functional Programming] Transition State based on Existing State using the State ADT (liftState, composeK)

    While sometimes outside input can have influence on how a given stateful transaction transitions, th ...

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

  3. [Functional Programming] Pull Many Random Numbers in a Single State ADT Transaction

    We have the ability to select a single random card from a pile of twelve cards, but we would like to ...

  4. [Functional Programming] Randomly Pull an Item from an Array with the State ADT (Pair)

    Functor composition is a powerful concept that arises when we have one Functor nested in another Fun ...

  5. [Functional Programming + React] Provide a reasonable default value for mapStateToProps in case initial state is undefined

    For example we have a component, it needs to call 'react-redux' connect function. import { compose, ...

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

  8. [Functional Programming Monad] Combine Stateful Computations Using A State Monad

    The true power of the State ADT really shows when we start combining our discrete, stateful transact ...

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

随机推荐

  1. Hadoop学习(6)-HBASE的安装和命令行操作和java操作

    使用HABSE之前,要先安装一个zookeeper 我以前写的有https://www.cnblogs.com/wpbing/p/11309761.html 先简单介绍一下HBASE HBASE是一个 ...

  2. java输入输出 -- java NIO之文件通道

    一.简介 通道是 Java NIO 的核心内容之一,在使用上,通道需和缓存类(ByteBuffer)配合完成读写等操作.与传统的流式 IO 中数据单向流动不同,通道中的数据可以双向流动.通道既可以读, ...

  3. Power BI学习

    常见用途: 1.连接数据 2.转换和清洗该数据,以创建数据模型 3.创建视觉对象,如提供数据的可视化表示形式的图表或图形 4.在一个或者多个报表页上创建作为视觉对象集合的报表 5.使用Power BI ...

  4. go 函数 命名返回值

    Go 的返回值可以被命名,并且像变量那样使用. 返回值的名称应当具有一定的意义,可以作为文档使用. 没有参数的 return 语句返回结果的当前值.也就是`直接`返回. 直接返回语句仅应当用在像下面这 ...

  5. 剑指offer(9)——用两个栈实现队列

    题目: 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 思路: 首先定义两个栈stack1. ...

  6. Once in a casino CodeForces - 1120B (暴力)

    大意: 给定两个字符串$a,b$, 每个字符为$0-9$, 每次操作将$a$中相邻两位加$1$或减$1$, 操作后每个数仍要为$0-9$, 求最少操作使$a$变成$b$. 先不考虑范围, 判断是否成立 ...

  7. Android Studio 代码页跳界面 /java和XML快速切换技巧

    https://www.cnblogs.com/simadi/p/6698666.html?utm_source=itdadao&utm_medium=referral 今天又发现了一个And ...

  8. ASP.NET WEB应用程序(.network4.5)MVC Razor视图引擎2 动态数据的呈现

    https://www.cnblogs.com/cynchanpin/p/7065098.html 在MVC3開始.视图数据能够通过ViewBag属性訪问.在MVC2中则是使用ViewData.MVC ...

  9. RGB转YUV 各种库的性能比较

    分辨率   1920*1080 平台  : X64  Windows  VS2015 测试  BGR24-->YUV420 trans_scale: 4.14 ms (自己写得)libyuv  ...

  10. epoll、mysql概念及简单操作

    epoll 程序阻塞的过程 假设我们目前运行了三个进程A B C ,如果他们都在处于运行态,那就会被加到一个运行队列中 进程A正在运行socket程序 在linux中有句话,万物皆文件,socket对 ...