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. 破解神器Hashcat使用简介

    0x00 背景 目前GPU的速度越来越快,使用GPU超强的运算速度进行暴力密码破解也大大提高了成功率,曾经看到老外用26块显卡组成的分布式破解神器让我羡慕不已.要说目前最好的GPU破解HASH的软件, ...

  2. bzoj 1590: [Usaco2008 Dec]Secret Message 秘密信息

    1590: [Usaco2008 Dec]Secret Message 秘密信息 Description     贝茜正在领导奶牛们逃跑.为了联络,奶牛们互相发送秘密信息.     信息是二进制的,共 ...

  3. LeetCode:删除排序数组中的重复项 (Remove Duplicates from Sorted Array)

    public class RemoveDuplicates { /** * 修改数组,使数组有序不重复.超出长度不考虑. * @param 排序数组 * @return 数组不重复数的个数 */ pu ...

  4. IT程序猿们,我该做什么选择呢

    这个时刻,我想我遇到人生小拐点了,程序猿到了30岁,到达了一个分界线了,现在的我该何去何从呢? 先谈下简单的情况吧: 来这个公司2年了,之前因为身体的原因,不想那么累,于是选择了一份维护的工作,就来了 ...

  5. 使用 NuGet 更新套件時將 jQuery 升級到 2.0.2 應該如何降級

    我們在 Visual Studio 2012 裡面會使用 NuGet 管理員管理那些常用的開發函式庫,例如jQuery.Json.NET. EntityFramework.ELMAH.… 等等.各位可 ...

  6. 用Qemu模拟vexpress-a9 (七) --- 嵌入式设备上安装telnet服务

    转载: http://blog.csdn.net/liuqz2009/article/details/6921789 Telnet协议是登陆远程网 络主机最简单的方法之一,只是安全性非常低.对targ ...

  7. x-superobject

    x-superobject GITHUB: https://github.com/onryldz/x-superobject **Delphi Cross Platform Rapid JSON**- ...

  8. 如何使用 Core Plot 的 API 帮助文档

    Core Plot 可是 iOS 下绝好的图表组件,虽说它的相关资料不甚丰富,特别是中文的,英文的还是有几篇不错的文章,不过 Core Plot 自身提供的 API 帮助文档,以及代码示例其实很有用的 ...

  9. [翻译] RBBAnimation,让你使用关键帧动画更便利

    RBBAnimation RBBAnimation is a subclass of CAKeyframeAnimation that allows you to declare your anima ...

  10. java获取http请求的Header和Body

    在http请求中,有Header和Body之分,读取header使用request.getHeader("..."); 读取Body使用request.getReader(),但g ...