[Functional Programming] mapReduce over Async operations and fanout results in Pair(rejected, resolved) (fanout, flip, mapReduce)
This post is similar to previous post. The difference is in this post, we are going to see how to handle both successfuly result and error result by using Pair functor.
So, still we have our funs.js: which is the same as previous post.
const fs = require('fs');
const {Async, constant, composeK, curry} = require('crocks');
const {fromNode} = Async;
const access = fromNode(fs.access);
const readFile = fromNode(fs.readFile);
const accessAsync = curry((mode, path) =>
access(path, mode)
.map(constant(path)));
// readFileAsync :: Option -> a -> Async Error b
const readFileAsync = curry((option, path) =>
readFile(path, option));
const checkRead = accessAsync(fs.constants.F_OK);
const readTextFile = readFileAsync('utf-8');
// loadTextFile :: String -> Async Error String
const loadTextFile = composeK(
readTextFile,
checkRead
);
const fork = a => a.fork(
console.log.bind(null, 'rej'),
console.log.bind(null, 'res')
);
module.exports = {
loadTextFile,
fork
}
For our main.js, we still have the same data input:
const data = [
'text.txt',
'text.big.txt',
'notfound.txt',
];
This time the difference of requirements are:
1. we want to read those files one by one, keep all the successfully results in Pair(result, _);
2. we want to keep the error result in Pair(_, error);
const concatSpecial = (acc, currAsync) =>
acc.chain(
xs => currAsync.bimap(
e => Pair(xs, e),
currVal => xs.concat(currVal))
); // Async (Pair [String] Error) [String]
const flow = mapReduce(
loadTextFile,
concatSpecial,
Async.Resolved([])
); flow(data).fork(
e => console.log(e.snd(), e.fst()), // Pair(success, error)
r => console.log(r), // Just success result
)
We are still using 'mapRedcue' to map over each filename, fetching the content; then we call 'concatSpecial' method, we want to concat all the successful result into one array. Therefore we give an empty array wrapped in Async:
const flow = mapReduce(
loadTextFile,
concatSpecial,
Async.Resolved([])
);
We can do some pointfree refactor for 'concatSpical', it's not necssary, but just as a partice:
const fn = flip(
xs => bimap(
e => Pair(xs, e),
currVal => xs.concat(currVal)
)
); const concatSpecial = (acc, currAsync) =>
acc.chain(
fn(currAsync)
);
For the function 'fn', we should take 'xs' as first param, then 'currAsync' as second param.
But since we also pass in 'currAsync' as first param, then we need to use 'flip':
acc.chain(
fn(currAsync) // pass currAsync as firt, then xs => fn(currAsync)(xs)
);
We can also replace 'Pair' with 'fanout':
const fn = flip(
xs => bimap(
fanout(constant(xs), identity),
currVal => xs.concat(currVal)
)
);
---
Full code:
const {fork, loadTextFile} = require('./funs.js');
const {Async, bimap, fanout, constant, flip, Pair, identity, mapReduce} = require('crocks');
const data = [
'text.txt',
'text.big.txt',
'notfound.txt',
];
const fn = flip(
xs => bimap(
e => Pair(xs, e),
fanout(constant(xs), identity),
currVal => xs.concat(currVal)
)
);
/*
const concatSpecial = (acc, currAsync) =>
acc.chain(
xs => currAsync.bimap(
e => Pair(xs, e),
currVal => xs.concat(currVal))
);*/
const concatSpecial = (acc, currAsync) =>
acc.chain(
fn(currAsync)
);
// Async (Pair [String] Error) [String]
const flow = mapReduce(
loadTextFile,
concatSpecial,
Async.Resolved([])
);
flow(data).fork(
e => console.log(e.snd(), e.fst()), // Pair(success, error)
r => console.log(r), // Just success result
)
[Functional Programming] mapReduce over Async operations and fanout results in Pair(rejected, resolved) (fanout, flip, mapReduce)的更多相关文章
- [Functional Programming] mapReduce over Async operations with first success prediction (fromNode, alt, mapReduce, maybeToAsync)
Let's say we are going to read some files, return the first file which pass the prediction method, t ...
- [Functional Programming] Use Task/Async for Asynchronous Actions
We refactor a standard node callback style workflow into a composed task-based workflow. Original Co ...
- [Functional Programming] Reader with Async ADT
ReaderT is a Monad Transformer that wraps a given Monad with a Reader. This allows the interface of ...
- Functional Programming without Lambda - Part 2 Lifting, Functor, Monad
Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...
- Monad (functional programming)
In functional programming, a monad is a design pattern that defines how functions, actions, inputs, ...
- JavaScript Functional Programming
JavaScript Functional Programming JavaScript 函数式编程 anonymous function https://en.wikipedia.org/wiki/ ...
- Beginning Scala study note(4) Functional Programming in Scala
1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...
- Functional Programming without Lambda - Part 1 Functional Composition
Functions in Java Prior to the introduction of Lambda Expressions feature in version 8, Java had lon ...
- a primary example for Functional programming in javascript
background In pursuit of a real-world application, let’s say we need an e-commerce web applicationfo ...
随机推荐
- [BZOJ4565][HAOI2016]字符合并(区间状压DP)
https://blog.csdn.net/xyz32768/article/details/81591955 首先区间DP和状压DP是比较明显的,设f[L][R][S]为将[L,R]这一段独立操作最 ...
- 【扩展欧几里得】codevs1200-同余方程
[题目大意] 求关于 x 同余方程 ax ≡ 1 (mod b)的最小正整数解. [思路] 求解ax+by=1,只要x<0就不断加上 b. #include<iostream> #i ...
- 20162327WJH实验五——数据结构综合应用
20162327WJH实验五--数据结构综合应用 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验密级: 非密 ...
- java线程本地变量
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为Thre ...
- A server is already running. Check /home/peter/stock/tmp/pids/server.pid. Exiting【Xshell 运行rails s 报错】
- java知识回顾
一.构造方法能不能被继承 当然不能,1.构造方法是类的唯一入口 2.构造方法与类名相同 3.子类构造方法中隐式的调用了父类的构造方法 二.值传递和引用传递.不变类和可变类.直接赋值和浅拷贝和深拷贝 ...
- 在没有界面的类中,实现弹出UIAlertView || 在没有界面的类中,刷新程序界面 思路
+(DisplayErrorMsg *)sharedDisplayErrorMsg { static DisplayErrorMsg *instance = nil; @synchronized(in ...
- 演示Microsoft Advertising SDK for Windows Phone 8.1
演示Microsoft Advertising SDK for Windows Phone 8.1,Only for Windows Phone 8.1 1.在References上点右键,添加引用, ...
- C# 结构体定义 转换字节数组 z
客户端采用C++开发,服务端采用C#开发,所以双方必须保证各自定义结构体成员类型和长度一致才能保证报文解析的正确性. [StructLayoutAttribute(LayoutKind.Sequent ...
- waitdialogform z
namespace DevExpress.Utils { using DevExpress.LookAndFeel; using DevExpress.Skins; using DevExpress. ...