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)的更多相关文章

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

  2. [Functional Programming] Use Task/Async for Asynchronous Actions

    We refactor a standard node callback style workflow into a composed task-based workflow. Original Co ...

  3. [Functional Programming] Reader with Async ADT

    ReaderT is a Monad Transformer that wraps a given Monad with a Reader. This allows the interface of ...

  4. Functional Programming without Lambda - Part 2 Lifting, Functor, Monad

    Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...

  5. Monad (functional programming)

    In functional programming, a monad is a design pattern that defines how functions, actions, inputs, ...

  6. JavaScript Functional Programming

    JavaScript Functional Programming JavaScript 函数式编程 anonymous function https://en.wikipedia.org/wiki/ ...

  7. Beginning Scala study note(4) Functional Programming in Scala

    1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...

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

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

随机推荐

  1. BZOJ 1975: [Sdoi2010]魔法猪学院 大水题 第k短路 spfa

    https://www.lydsy.com/JudgeOnline/problem.php?id=1975 我好像到现在了第k短路都不会写,mdzz. 先spfa求出最短路,然后扫点存各种前置路径已经 ...

  2. HDU 5699 货物运输 二分

    货物运输 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5699 Description 公元2222年,l国发生了一场战争. 小Y负责领导工人运输物 ...

  3. Codeforces Beta Round #11 A. Increasing Sequence 贪心

    A. Increasing Sequence 题目连接: http://www.codeforces.com/contest/11/problem/A Description A sequence a ...

  4. HDU 1698 just a hook 线段树,区间定值,求和

    Just a Hook Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1 ...

  5. poj 1825 Ants 水题

    Ants Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10722   Accepted: 4752 Description ...

  6. [Visual Studio] SOA服务框架搭建

    1.服务框架搭建 2.服务模板创建 3.Nuget引用 4.客户端调用 任务点: 1.分析SOA 2.修改SOA架构名称以及关键字 3.使用Nuget添加引用 4.选择服务模板进行创建 5.尝试调用 ...

  7. Redis_常见JedisConnectionException异常分析

    最近项目开发中用到了Redis, 选择了官网推荐的java client Jedis.Redis常用命令学习:http://redis.io/commandsRedis官方推荐Java客户端Jedis ...

  8. Maven系列--setting.xml 配置详解

    文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...

  9. 2008 SCI 影响因子(Impact Factor)

    2008 SCI 影响因子(Impact Factor) Excel download 期刊名缩写 影响因子 ISSN号 CA-CANCER J CLIN 74.575 0007-9235 NEW E ...

  10. [Node.js]Express web框架

    摘要 Express是一个简洁灵活的node.js web应用框架,提供了一系列强大特性帮助你创建各种web应用和丰富的http工具.使用express可以快速创建一个完整功能的网站. Express ...