We see three varied examples of where natural transformations come in handy.

Let's mark the law here for Natural Transformations:

nt(F).map(f) === nf(F.map(f))

Then let's see why we might need to apply Natural Transformations:

1. Natural Transformations can improve the code proformance

For example, we have an array of numbers, we want to get larger number, apply a doulbe function, then only get first element out of the array.

const first = xs => fromNullable(xs[]);
const largeNumbers = xs => xs.filter(x => x > );
const doulbe = x => x * ; // We first run though the whole array to doulbe the number
// Then apply first to either transform -> Proformance cost
// Since nt(F).map(f) === nt(F.map(f))
const transform1 = xs => first(largeNumbers(xs).map(doulbe));
const app = xs => transform1(xs);
console.log(app([,,,])); // Either { value: 800 }

Imporved one should be get only first of larger number, then apply transform:

const first = xs => fromNullable(xs[]);
const largeNumbers = xs => xs.filter(x => x > );
const doulbe = x => x * ; // Now we get first of array and transform to either, then apply our doulbe function
const transform2 = xs => first(largeNumbers(xs)).map(doulbe);
const app = xs => transform2(xs);
console.log(app([,,,])); // Either { value: 800 }

2. Solve different nested Functors:

const fake = id =>
({id, name: 'user1', best_friend_id: id + });
// Db :: find :: id -> Task(Either)
const Db = ({
find: id => new Task((rej, res) => {
res(id > ? Right(fake(id)): Left('not found'))
})
});

For example, the code above, we have a Db.find function, which return Task(Either(User)). It would be much easier for us to work with the same Functor type, instead of multi functors. we can think about change

// Either -> Task
const eitherToTask = e =>
e.fold(Task.rejected, Task.of);

With this tool, let's see how it solve us problem:

Db.find() // Task(Right(User))

Now we chain 'eitherToTask':

Db.find() // Task(Right(User))
.chain(eitherToTask) // // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)

So after run though 'eitherToTask' we change 'Right to Task' we got 'Task(Task(User)), then the outmost 'chain' will remove 'Task(User)'

Now if we want to find User's best friend id:

Db.find() // Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)
.chain(user => Db.find(user.best_friend_id)) // Task(User) --Db.find--> Task(Task(Right(User))) --chain--> Task(Right(User))

We know that 'Db.find(user.best_friend_id)' returns 'Task(Right(User))', inner most function call return 'Task(Task(Right(User)))', after outter most 'chain', we got 'Task(Right(User))'.

Now we can apply the trick again:

Db.find() // Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)
.chain(user => Db.find(user.best_friend_id)) // Task(User) --Db.find--> Task(Task(Right(User))) --chain--> Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)

We only got 'Task(User)' in the end, ready to be forked!

Db.find() // Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)
.chain(user => Db.find(user.best_friend_id)) // Task(User) --Db.find--> Task(Task(Right(User))) --chain--> Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)
.fork(console.error, console.log); // { id: 5, name: 'user1', best_friend_id: 6 }

--

const Either = require('data.either');
const Task = require('data.task');
const {List, Map} = require('immutable-ext');
const {Right, Left, fromNullable} = Either; const log = console.log; // F a -> G a
// nt(F).map(f) === nt(F.map(f)) //////Exp1/////
const res = List(['Hello', 'wolrd']).chain(x => x.split(''));
console.log(res.toJS()); // [ 'H', 'e', 'l', 'l', 'o', 'w', 'o', 'l', 'r', 'd' ] //////Exp2/////
const first = xs => fromNullable(xs[]);
const largeNumbers = xs => xs.filter(x => x > );
const doulbe = x => x * ; // We first run though the whole array to doulbe the number
// Then apply first to either transform -> Proformance cost
// Since nt(F).map(f) === nt(F.map(f))
const transform1 = xs => first(largeNumbers(xs).map(doulbe));
// Now we get first of array and transform to either, then apply our doulbe function
const transform2 = xs => first(largeNumbers(xs)).map(doulbe);
const app = xs => transform2(xs);
console.log(app([,,,])); // Either { value: 800 } //////Exp3/////const fake = id =>
({id, name: 'user1', best_friend_id: id + });
// Db :: find :: id -> Task(Either)
const Db = ({
find: id => new Task((rej, res) => {
res(id > ? Right(fake(id)): Left('not found'))
})
}); const eitherToTask = e =>
e.fold(Task.rejected, Task.of); Db.find() // Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)
.chain(user => Db.find(user.best_friend_id)) // Task(User) --Db.find--> Task(Task(Right(User))) --chain--> Task(Right(User))
.chain(eitherToTask) // Task(Right(User)) --EtT--> Task(Task(User)) --chain--> Task(User)
.fork(console.error, console.log); // { id: 5, name: 'user1', best_friend_id: 6 }

[Compose] 21. Apply Natural Transformations in everyday work的更多相关文章

  1. [Compose] 20. Principled type conversions with Natural Transformations

    We learn what a natural transformation is and see the laws it must obey. We will see how a natural t ...

  2. [Compose] 16. Apply multiple functors as arguments to a function (Applicatives)

    We find a couple of DOM nodes that may or may not exist and run a calculation on the page height usi ...

  3. JDK8新特性 -- Function接口: apply,andThen,compose

    1 Function<T, R>中的T, R表示接口输入.输出的数据类型. R apply(T t) apply: .例子:func是定义好的Function接口类型的变量,他的输入.输出 ...

  4. [转]Neural Networks, Manifolds, and Topology

    colah's blog Blog About Contact Neural Networks, Manifolds, and Topology Posted on April 6, 2014 top ...

  5. 壁虎书2 End-to-End Machine Learning Project

    the main steps: 1. look at the big picture 2. get the data 3. discover and visualize the data to gai ...

  6. 2020你还不会Java8新特性?

    Java8(1)新特性介绍及Lambda表达式 前言: 跟大娃一块看,把原来的电脑拿出来放中间看视频用 --- 以后会有的课程 难度 深入Java 8 难度1 并发与netty 难度3 JVM 难度4 ...

  7. [转载] 首席工程师揭秘:LinkedIn大数据后台是如何运作的?(一)

    本文作者:Jay Kreps,linkedin公司首席工程师:文章来自于他在linkedin上的分享:原文标题:The Log: What every software engineer should ...

  8. [Javascript] Functor law

    Functor laws: 1. Identity: map(id) == id 2. Composition: compose(map(f), map(g)) == map(compose(f,g) ...

  9. Category Theory: 01 One Structured Family of Structures

    Category Theory: 01 One Structured Family of Structures 这次看来要放弃了.看了大概三分之一.似乎不能够让注意力集中了.先更新吧. 群的定义 \( ...

随机推荐

  1. 2015年9月10-11日,杨学明老师《IPD DRY RUN》专题培训在武汉某上市企业成功举办!

    2015-9-10~11日,杨学明老师为武汉著名的光通信企业某上市公司实施了为期两天的“IPD DRY RUN”,开班前,该公司三个项目团队的负责人先后发言,烽火PMO部门领导和公开研发部网管系统的领 ...

  2. 作死遇到的坑--view向下偏移

    好大一个坑.--谈谈view偏移问题: 先上张图, 图中白色部分.上面的是从网上找的资源.将导航栏隐藏之后用collectionView加上去而实现的滑动标签功能.开始以为是代码中的问题.然后仔细推敲 ...

  3. openSUSE 13.1 Milestone 4 发布

    openSUSE 13.1 发布第四个里程碑版本,下载地址: openSUSE-Factory-KDE-Live-Build0652-x86_64.iso (949MB, MD5, torrent) ...

  4. Asp.Net Web API 2第十五课——Model Validation(模型验证)

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文参考链接文章地址htt ...

  5. Kali Linux Web 渗透测试视频教程— 第十六课-拒绝服务攻击

    Kali Linux Web 渗透测试视频教程— 第十六课-拒绝服务攻击 文/玄魂 目录 Kali Linux Web 渗透测试视频教程— 第十六课-拒绝服务攻击................... ...

  6. Mac系统下lipo, ar, nm等工具的使用简介

    引言 开发第三方库时, 如果没有进行特殊处理, 很容易把其他第三方库的符号暴露出来, 导致链接时产生符号重复. 如下图所示 如果用户链接了其他版本的libjpeg, 会因为入口地址不正确让程序直接崩溃 ...

  7. Atitit.java eval功能的实现  Compiler API

    Atitit.java eval功能的实现  Compiler API 输出echo2 输出目录配置2 针对编译器,JDK 设计了两个接口,分别是 JavaCompiler 和JavaCompiler ...

  8. Lucene.net入门学习(结合盘古分词)

    Lucene简介 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整 ...

  9. IOS设计模式浅析之简单工厂模式(SimpleFactory)

    概述 首先说明一下,简单工厂模式不属于23种GOF设计模式之一.它也称作静态工厂方法模式,是工厂方法模式的特殊实现.这里对简单工厂模式进行介绍,是为本系列后面的工厂方法和抽象工厂模式做一个引子. 定义 ...

  10. iOS开发---集成百度地图,位置偏移问题

    iOS 集成百度SDK 请参考 百度地图官方文档 ,这里不就多啰嗦了 本文介绍的是在百度地图上根据经纬度,自定义气泡时,气泡位置的偏移,在我们天朝这种事是很常见的,也见怪不怪了,在项目中使用的百度地图 ...