[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 ...
随机推荐
- 女友要下岗?Windows 10的Cortana何方妖孽?
在Windows 10中,一大特色就是内置的Cortana小娜.她的出现为广大单身贵族带来了福音,就连天天秀恩爱的情侣也有了危机感. 小娜,你这样夺位这样真的好么? 还不帮我快快开始搜索 从Windo ...
- [leetcode 226] Invert Tree
1 题目: Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 2 思路: 这是因为谷歌面试xx而 ...
- php乱码
1:php 编码是utf-8 但是接口需要是gbk 这么办?? $message = "你的微点管理地址为:".$shortUrl." [请保存信息]"; // ...
- Jeasyframe 开源框架 稳定版 V1.5 发布
这是Jeasyframe开源框架的第一个稳定版本,感谢一起帮忙测试并给予反馈的网友们. 框架官网:http://www.jeasyframe.org/ 产品介绍: Jeasyframe开源框架是基于S ...
- C#函数式编程之标准高阶函数
何为高阶函数 大家可能对这个名词并不熟悉,但是这个名词所表达的事物却是我们经常使用到的.只要我们的函数的参数能够接收函数,或者函数能够返回函数,当然动态生成的也包括在内.那么我们就将这类函数叫做高阶函 ...
- 跟我一起学WCF(9)——WCF回调操作的实现
一.引言 在上一篇文章中介绍了WCF对Session的支持,在这篇文章中将详细介绍WCF支持的操作.在WCF中,除了支持经典的请求/应答模式外,还提供了对单向操作.双向回调操作模式的支持,此外还有流操 ...
- C#设计模式(5)——建造者模式(Builder Pattern)
一.引言 在软件系统中,有时需要创建一个复杂对象,并且这个复杂对象由其各部分子对象通过一定的步骤组合而成.例如一个采购系统中,如果需要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象, ...
- 设计模式之美:Structural Patterns(结构型模式)
结构型模式涉及到如何组合类和对象以获得更大的结构. 结构型类模式采用继承机制来组合接口实现. 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法. 因为 ...
- ibatis + log4net 配置注意事项
一 在web.config或app.config中配置 <configuration> <configSections> <sectionGroup name=" ...
- 有关CSS中字体响应式的设置
在进行页面响应式设计中,往往需要根据屏幕分辨率来显示不同大小的字体.通常的做法是通过media queries给不同的分辨率指定不同的字体样式,例如: body { font-size: 22px; ...