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的更多相关文章

  1. [Compose] 21. Apply Natural Transformations in everyday work

    We see three varied examples of where natural transformations come in handy. const Right = x => ( ...

  2. 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 ...

  3. Type conversions in C++类型转换

    ###Implicit conversions隐式转换* 可以在基本类型之间自由转换:* 可以把任何类型的pointer转换为void pointer:* 可以将子类pointer转换为基类point ...

  4. C语言 结构体指针赋值 incompatible types when assigning to type 'char[20]' from type 'char *'

    strcpy(pstudent->name, "guo zhao wei "); 为什么错误,该怎么写,(红色行)     追问 为什么不能直接赋值啊, 追答 用char n ...

  5. 条款24:若所有参数皆需要类型转换,请为此采用non-member函数(Declare non-member functions when type conversions should apply to all parameters)

    NOTE: 1.如果你需要为某个函数的所有参数(包括this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member.

  6. C++: Type conversions

    1.static_cast     static_cast可以转换相关联的类,可以从子类转换成父类.也能从父类转向子类,但是如果转换的父类指针(或者父类引用)所指向的对象是完整的,那么是没有问题:但是 ...

  7. Type Systems

    This section deals with more theoretical aspects of types. A type system is a set of rules used by a ...

  8. python3.4 data type

    #coding=utf-8 #Python 3.4 https://docs.python.org/3.4/library/ #IDE:Eclipse +PyDev Window10 import a ...

  9. 转载:oracle 自定义类型 type / create type

    标签:type create oracle object record 一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarc ...

随机推荐

  1. 技术文档--volley 框架

    Volley 框架 参考文档:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73e7e808c027fa ...

  2. C#函数式编程之缓存技术

    缓存技术 该节我们将分成两部分来讲解,第一部分为预计算,第二部分则为缓存.缓存这个技术对应从事开发的人员来说是非常熟悉的,从页面缓存到数据库缓存无处不在,而其最重要的特点就是在第一次查询后将数据缓存, ...

  3. python 列表生成器

    python 列表生成器 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 一个循环 在C语言等其他语言中,for循环一般是这样的 ...

  4. 2014-3-11 星期二 晴 [卓有成效 master 摸索计划方案]

    今日总结: [汇编]:StudyNew+ReView-->[中]上机,还行,学点新知识 [英语]:Study-->[中]发现这个要变得好啦 [----]:lib [----]:lib--& ...

  5. 最新 Windows 10 应用项目模板发布

    以下是最新的Visual Studio 2015 Windows 10 应用程序模板. Windows 10中几乎所有的官方应用都遵循这样一个设计模板:在左上方有一个所谓的导航栏.点击该导航按钮,左侧 ...

  6. ASP.NET 5系列教程 (六): 在 MVC6 中创建 Web API

    ASP.NET 5.0 的主要目标之一是统一MVC 和 Web API 框架应用. 接下来几篇文章中您会了解以下内容: ASP.NET MVC 6 中创建简单的web API. 如何从空的项目模板中启 ...

  7. paip. 定时 关机 休眠 的总结

    paip. 定时 关机 休眠 的总结 //////////////////title bat shell 批处理日期时间的使用比较. bat shell 批处理if else 多行.. 作者Attil ...

  8. RAR和ZIP:压缩大战真相

    转:http://fqd2eh4y.blog.163.com/blog/static/69195855200801035015857 前言--王者归来? 等待足足两年之久,压缩霸主WinZip终于在万 ...

  9. 上海SAP代理商 电子行业ERP系统 SAP金牌代理商达策

    上海SAP代理商 电子行业ERP系统 SAP金牌代理商达策上海达策为电子行业企业提供了多样的ERP信息化管理系统.基于多营运中心的管理架构体系,构造了以供应链.生产管理.财务一体化为核心,协同HR.B ...

  10. 爬虫神器xpath的用法(一)

    1.如果你没有安装lxml,请运行pip install lxml或者easy_install lxml安装,如果在安装过程中失败的话, 是因为lxml需要依赖某些库文件,具体可以问下度娘,这里不再赘 ...