[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 ...
随机推荐
- HIVE几种数据导入方式
HIVE几种数据导入方式 今天的话题是总结Hive的几种常见的数据导入方式,我总结为四种:(1).从本地文件系统中导入数据到Hive表:(2).从HDFS上导入数据到Hive表:(3).从别的表中查询 ...
- Objective 笔记C(第二天)
属性本质 •什么是属性 在OC中,属性提供了setter和getter方法,本质上属性就是方法,属性的值是由实例变量来保存的. • 属性的本质(一般三个部分组成) a.保存属性值的实例变量int _a ...
- Android 自定义View 三板斧之一——继承现有控件
通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 本文重点讨论继承现有 ...
- linux下卸载mysql
卸载mysql rpm -qa|grep -i mysql rpm -ev MySQL-server-4.0.14-0 MySQL-client-4.0.14-0 卸载后/var/lib/mysql中 ...
- 使用NHibernate(9)-- 缓存
1,对象状态. 作为基础,还是先看一下对象的状态吧.主要涉及到三个名词,瞬时.持久.托管. 瞬时态:对象刚创建,Session还不知道这个对象的存在.可以通过调用ISession的Save等方法可以转 ...
- 大熊君说说JS与设计模式之------代理模式Proxy
一,总体概要 1,笔者浅谈 当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种. 代理模式是比较有用途的一 ...
- Ora-01536:超出了表空间users的空间限量(转)
Ora-01536:超出了表空间users的空间限量(转) 正在开会,同事跑过来说数据库有问题,通讯程序不能入库,赶快获取一条insert into a values()语句后在toad工具中手动插入 ...
- 找出数组中最长的连续数字序列(JavaScript实现)
原始题目: 给定一个无序的整数序列, 找最长的连续数字序列. 例如: 给定[100, 4, 200, 1, 3, 2], 最长的连续数字序列是[1, 2, 3, 4]. 小菜给出的解法: functi ...
- paip.提高稳定性---自动检测sleep mysql数据库死连接以及kill
paip.提高稳定性---自动检测sleep mysql数据库死连接以及kill 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:ht ...
- Python类
在类的变量前面加 _ _ 是私有变量,外部不可访问. 需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是 ...