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. sqlserver2005版本的mdf文件,还没有log文件,

    https://www.cnblogs.com/wanglg/p/3740129.html  来自此文 仅做备忘  感谢提供信息让我处理好此问题 sqlserver mdf向上兼容附加数据库(无法打开 ...

  2. javaIO -- 流的体系设计思路、基础分类

    一.流 1. 流的含义 在程序设计中,流是对于数据流动传输的一种抽象描述任何有能力产出数据的数据源,或者有能力接受数据的接收端对象都是一个流. 2. 流的源和目的 数据可能从本地文件读取,或者写入,  ...

  3. Erlang:[笔记三,构建工具rebar之使用依赖]

    概述 类似Java中的Maven,Gradle,在Erlang中同样也有包管理的工具,Rebar提供Erlang依赖(包)管理机制,开发人员可以重复使用已有的模块,通过rebar引入自己的项目直接使用 ...

  4. python读写文件的操作

    编程语言中,我们经常会和文件和文件夹打交道,这篇文章主要讲的是Python中,读写文件的常用操作: 一.打开文件 openFile = open('../Files/exampleFile.txt', ...

  5. WUSTOJ 1241: 到底是几月几日?(Java)

    1241: 到底是几月几日? 题目   输入年月日,输出当前日期是当年的第几天,输入年份和第几天,输出当前日期.更多内容点击标题. 说明   算是水题吧,仅提供代码做参考,不做分析.代码没用JDK自带 ...

  6. STM32固件库模板下载以及固件库学习方法

    固件库模板下载 固件库模板新建过程: 下载我们上节的固件库文件 电脑新建一个文件夹命名为Fwlib-Template,在此文件夹下分别新建DOC Libraries Project User 这四个文 ...

  7. go slice切片注意跟数组的区别

    一个 slice 会指向一个序列的值,并且包含了长度信息. []T 是一个元素类型为 T 的 slice. [2]string 这样定义久是字符数组 []string 这样定义就是切片 表面上看切片就 ...

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

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

  9. ORACLE:锁被未决分布式事务处理 18.27.160617 持有

    1. 以管理员账号登陆 2. rollback  force '18.27.160617 ';

  10. Plugin 免费CSS生成器CssCollector

    下载: 百度云 自己在做Web开发的时候,页面里会有很多样式类,一个个复制到样式表里总感觉很麻烦 网上也没有找到合适的工具,可以一键生成样式表 所以,干脆自己做一个咯~ 案例展示 花了一天时间,CSS ...