[Compose] 20. Principled type conversions with Natural Transformations
Natural Transformations, let's explain it by using a coding example, for example, we have a 'Either' holding a value 'a' and we want to transform a' Task' that holding an 'a'.
// Either(a) -> Task(a)
Let's start coding:
const Either = require('data.either');
const {Right, Left, fromNullable} = Either;
const Task = require('data.task');
const eitherToTask = e =>
e.fold(Task.rejected, Task.of);
eitherToTask(Right('Good')).fork(
e => console.error('err', e),
x => console.log('res', a)
) // 'res' Good
Let's go thought:
const eitherToTask = e =>
e.fold(Task.rejected, Task.of);
'Either' has 'fold' method (left, right), as we know 'fold' will unbox the contianer just return the value, so that it will unbox the 'Either' type, and we wrap the return value with 'Task'. So now, 'eitherToTask' return a 'Task'
eitherToTask(Right('Good')).fork(...)
The result we using 'Right' instead of 'Left' we will explain later, but here, we know we have a 'Task', therefore we can call 'fork' to trigger the side effect.
Law:
natural_transform(Functor).map(function) === natural_transform(Functor.map(function))
On the left side of equals, we have natural transform function wraps a Functor, then map to a function.
On the right side, we have a natural transform function wrap functor that map to a funciton.
Let's see an example:
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x)
})
const boxToEither = b =>
b.fold(Right);
const res1 = boxToEither(Box()).map(x => x * );
console.log(res1); // Either (200)
const res2 = boxToEither(Box().map(x => x * ));
console.log(res2); // Either (200)
What if we using 'Left' instead of 'Right':
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x)
})
const boxToEither = b =>
b.fold(Left);
const res1 = boxToEither(Box()).map(x => x * );
console.log(res1); // Either(100)
const res2 = boxToEither(Box().map(x => x * ));
console.log(res2); // Either(200)
As we can see 'res1' is no longer equals to 'res2', because Left will ingore mapping function.
Another example: List -> Either:
// first :: [] -> Either
const first = xs => fromNullable(xs[]);
const res3 = first([,,]).map(x => x +);
const res4 = first([,,].map(x => x +));
console.log(res3); // Either(2)
console.log(res4); // Either(2)
These two shall be equal and they are. Any function that satisfies this equation is a natural transformation. Let's look at this on the board here.

If we have some F(a) and some functor holding an a and we map(f) over it, it transforms that a to a b. we're just mapping a function from the type a to some type b here all inside our functor f. Then we run a natural transformation we'll have a G(b).
If we take the other path moving downward we'll first naturally transform our functor holding an a into the G(a) here, and then we map(f) over that to get a G(b). We end up with the same result. This can be quite useful.
[Compose] 20. Principled type conversions with Natural Transformations的更多相关文章
- [Compose] 21. Apply Natural Transformations in everyday work
We see three varied examples of where natural transformations come in handy. const Right = x => ( ...
- A Tour of Go Type conversions
The expression T(v) converts the value v to the type T. Some numeric conversions: var i int = 42 var ...
- Type conversions in C++类型转换
###Implicit conversions隐式转换* 可以在基本类型之间自由转换:* 可以把任何类型的pointer转换为void pointer:* 可以将子类pointer转换为基类point ...
- C语言 结构体指针赋值 incompatible types when assigning to type 'char[20]' from type 'char *'
strcpy(pstudent->name, "guo zhao wei "); 为什么错误,该怎么写,(红色行) 追问 为什么不能直接赋值啊, 追答 用char n ...
- 条款24:若所有参数皆需要类型转换,请为此采用non-member函数(Declare non-member functions when type conversions should apply to all parameters)
NOTE: 1.如果你需要为某个函数的所有参数(包括this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member.
- C++: Type conversions
1.static_cast static_cast可以转换相关联的类,可以从子类转换成父类.也能从父类转向子类,但是如果转换的父类指针(或者父类引用)所指向的对象是完整的,那么是没有问题:但是 ...
- Type Systems
This section deals with more theoretical aspects of types. A type system is a set of rules used by a ...
- python3.4 data type
#coding=utf-8 #Python 3.4 https://docs.python.org/3.4/library/ #IDE:Eclipse +PyDev Window10 import a ...
- 转载:oracle 自定义类型 type / create type
标签:type create oracle object record 一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarc ...
随机推荐
- NSMutableAttributedString/NSAttributedString 富文本设置
今天在做项目的过程中,我们的设计师想要一种字体四周都带阴影的效果,但是我们平时使用的setShadowColor 和setShadowOffset是达不到这种效果,setShadowOffset 只能 ...
- Robberies(HDU2955):01背包+概率转换问题(思维转换)
Robberies HDU2955 因为题目涉及求浮点数的计算:则不能从正面使用01背包求解... 为了能够使用01背包!从唯一的整数(抢到的钱下手)... 之后就是概率的问题: 题目只是给出被抓的 ...
- 无线安全专题_破解篇02--kali破解pin码
最近项目有点紧,所以本应该上周发的文章,拖到了本周三,在此说声抱歉.无线安全专题,我打算系统地写六个部分,分别为破解篇,攻击篇,欺骗篇,路由篇,移动篇和蓝牙篇,当然在发布的过程中,可能还会掺杂着发布f ...
- SQLSERVER性能监控级别步骤
SQLSERVER性能监控级别步骤 下面先用一幅图描述一下有哪些步骤和顺序 1.识别瓶颈 识别瓶颈的原因包括多个方面,例如,资源不足,需要添加或升级硬件: 工作负荷在同类资源之间分布不均匀,例如,一个 ...
- 盘点国内网站常用的一些 CDN 公共库加速服务
CDN公共库是指将常用的JS库存放在CDN节点,以方便广大开发者直接调用.与将JS库存放在服务器单机上相比,CDN公共库更加稳定.高速.一 般的CDN公共库都会包含全球所有最流行的开源JavaScri ...
- ubuntu adobe flash player 安装
常规做法 1.先更新sudo apt-get update 2. sudo apt-get install flashplugin-installer 这次却卡在downloading这里 下不去.无 ...
- 初学者利用git 上传代码到Coding的简单操作步骤
1.首先登陆coding网站注册账号https://coding.net/ (注册完后需登陆邮箱激活邮件) 2.登陆刚注册的coding账号 ,添加项目 添加项目—〉输入项目名称—〉输入对项目的简单描 ...
- java5 Lock用法
锁是控制多个线程对共享资源进行访问的工具.通常,锁提供了对共享资源的独占访问.一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁.不过,某些锁可能允许对共享资源并发访问,如 ReadWri ...
- podspec文件介绍
podspec文件是cocopods引入的第三方代码库的配置索引文件 它的创建命令是:$pod spec create TestFile podspec文件的常用配置字段介绍 Pod::Spec.ne ...
- 深入理解HTML5:语义、标准与样式(勇猛精进早登大师殿堂创最优品质交互)
深入理解HTML5:语义.标准与样式(勇猛精进早登大师殿堂创最优品质交互) [美]布拉德福(Bradford,A.) [美]海涅(Haine,P.)著 高京译 ISBN 978-7-121-20552 ...