博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Compose] 20. Principled type conversions with Natural Transformations
阅读量:4972 次
发布时间:2019-06-12

本文共 2945 字,大约阅读时间需要 9 分钟。

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(100)).map(x => x * 2);console.log(res1);  // Either (200)const res2 = boxToEither(Box(100).map(x => x * 2));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(100)).map(x => x * 2);console.log(res1);  // Either(100)const res2 = boxToEither(Box(100).map(x => x * 2));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 :: [] -> Eitherconst first = xs => fromNullable(xs[0]);const res3 = first([1,2,3]).map(x => x +1);const res4 = first([1,2,3].map(x => x +1)); 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.

转载于:https://www.cnblogs.com/Answer1215/p/6215482.html

你可能感兴趣的文章
基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD)
查看>>
[django实践]投票app
查看>>
[django]form的content-type(mime)
查看>>
iOS开发遇到的坑之六--使用cocopods管理第三方库时,编译出现Library not found for -lPods问题的解决办法...
查看>>
javascript 点点滴滴 富文本编辑器的学习2
查看>>
JQUERY —— 绑定事件
查看>>
在TabControl中的TabPage选项卡中添加Form窗体
查看>>
inout port仿真
查看>>
oracle中SET DEFINE意思
查看>>
个人作业-最长英语链
查看>>
JMeter-性能测试之报表设定的注意事项
查看>>
1066-堆排序
查看>>
仿面包旅行个人中心下拉顶部背景放大高斯模糊效果
查看>>
强大的css3
查看>>
C#委托与事件
查看>>
Scala系列:注解
查看>>
Linux kernel 发布 5.0-rc1 版本
查看>>
[转帖]创建文件或修改文件时间 touch
查看>>
【转帖】Linux mount 域控权限的共享目录
查看>>
NSURLSession的简单使用
查看>>