Let's examine a pointfree way to write these applicative calls. Since we know map is equal to of/ap, we can write generic functions that will ap as many times as we specify:

const liftA2 = curry((g, f1, f2) => f1.map(g).ap(f2));

const liftA3 = curry((g, f1, f2, f3) => f1.map(g).ap(f2).ap(f3));

// liftA4, etc

Let's see the previous examples written this way:

const profile = name => email => `${name}__${email}`;
const safeProfile = liftA2(profile);
const res1 = safeProfile(prop('name', user), prop('email', user)); // John Doe__blurp_blurp
liftA2(add, Maybe.of(), Maybe.of());
// Maybe(5) liftA2(renderPage, Http.get('/destinations'), Http.get('/events'));
// Task('<div>some page with dest and events</div>') liftA3(signIn, getVal('#email'), getVal('#password'), IO.of(false));
// IO({ id: 3, email: 'gg@allin.com' })

liftAN: Lift a curry function into a Functor context, which will be define later;

liftA2(add, Maybe.of(2), Maybe.of(3)); Maybe will be the Functor context for 'add' function which has been lifted

Laws:

Identity

// identity
A.of(id).ap(v) === v;

For example:

const v = Identity.of('Pillow Pets');
Identity.of(id).ap(v) === v;

Homomorphism

// homomorphism
A.of(f).ap(A.of(x)) === A.of(f(x));

homomorphism is just a structure preserving map. In fact, a functor is just a homomorphism between categories as it preserves the original category's structure under the mapping.

A quick example:

Either.of(toUpperCase).ap(Either.of('oreos')) === Either.of(toUpperCase('oreos'));

Interchange

The interchange law states that it doesn't matter if we choose to lift our function into the left or right side of ap.

// interchange
v.ap(A.of(x)) === A.of(f => f(x)).ap(v);

Here is an example:

const v = Task.of(reverse);
const x = 'Sparklehorse'; v.ap(Task.of(x)) === Task.of(f => f(x)).ap(v);

Composition

// composition
A.of(compose).ap(u).ap(v).ap(w) === u.ap(v.ap(w));
const u = IO.of(toUpperCase);
const v = IO.of(concat('& beyond'));
const w = IO.of('blood bath '); IO.of(compose).ap(u).ap(v).ap(w) === u.ap(v.ap(w));

Examples:

const safeAdd = curry((a, b) => Maybe.of(add).ap(a).ap(b));
const safeAdd = liftA2(add); const localStorage = {
player1: { id:, name: 'Albert' },
player2: { id:, name: 'Theresa' },
}; // getFromCache :: String -> IO User
const getFromCache = x => new IO(() => localStorage[x]); // game :: User -> User -> String
const game = curry((p1, p2) => `${p1.name} vs ${p2.name}`);
// startGame :: IO String
const startGame = liftA2(game, getFromCache('player1'), getFromCache('player2'));

[Functional Programming] Working with two functors(Applicative Functors)-- Part2 --liftAN的更多相关文章

  1. [Functional Programming] Working with two functors(Applicative Functors)-- Part1 --.ap

    What is applicative functor: the ability to apply functors to each other. For example we have tow fu ...

  2. UCF Local Programming Contest 2016 J题(二分+bfs)

    题目链接如下: https://nanti.jisuanke.com/t/43321 思路: 显然我们要采用二分的方法来寻找答案,给定一个高度如果能确定在这个高度时是否可以安全到达终点,那我们就可以很 ...

  3. Programming | 中/ 英文词频统计(MATLAB实现)

    一.英文词频统计 英文词频统计很简单,只需借助split断句,再统计即可. 完整MATLAB代码: function wordcount %思路:中文词频统计涉及到对"词语"的判断 ...

  4. Coursera Algorithms Programming Assignment 4: 8 Puzzle (100分)

    题目原文:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html 题目要求:设计一个程序解决8 puzzle问题以及该问题的推广 ...

  5. Coursera Algorithms Programming Assignment 3: Pattern Recognition (100分)

    题目原文详见http://coursera.cs.princeton.edu/algs4/assignments/collinear.html 程序的主要目的是寻找n个points中的line seg ...

  6. The 2019 Asia Nanchang First Round Online Programming Contest C. Hello 2019(动态dp)

    题意:要找到一个字符串里面存在子序列9102 而不存在8102 输出最小修改次数 思路:对于单次询问 我们可以直接区间dpOn求出最小修改次数 但是对于多次询问 我在大部分题解看到的解释一般是用线段树 ...

  7. Functional Programming 资料收集

    书籍: Functional Programming for Java Developers SICP(Structure and Interpretation of Computer Program ...

  8. Sth about 函数式编程(Functional Programming)

    今天开会提到了函数式编程,针对不同类型的百年城方式,查阅了一部分资料,展示如下: 编程语言一直到近代,从汇编到C到Java,都是站在计算机的角度,考虑CPU的运行模式和运行效率,以求通过设计一个高效的 ...

  9. iOS 开发之函数式编程思想(Functional Programming)

    函数式编程(Functional Programming), 函数式编程强调的函数:1.不依赖外部状态:2.不改变外部状态. 函数式编程可解决线程安全问题,每一个函数都是线程安全的. 时间状态:变量一 ...

随机推荐

  1. 洛谷P3950 部落冲突 [LCT]

    题目传送门 部落冲突 格式难调,体面就不放了. 分析: julao们应该都看得出来就是个$LCT$板子,战争就$cut$,结束就$link$,询问就$find$.没了... 太久没打$LCT$,然后发 ...

  2. Python类总结-反射及getattr,setattr

    类反射的四个基本函数 hasattr getattr setattr delattr #反射 class BlackMedium: feature = 'Ugly' def __init__(self ...

  3. java -jar demo.jar

    部署springboot项目 生成jar包其实还是依赖springboot的jar才能跑起来,为什么呢? 1.在C盘手工创建了一个文件夹,是拷贝了demo.jar这个jar包运行是报错的. 2.在D: ...

  4. Linux 下安装gmpy2

    GMP(GNU Multiple Precision Arithmetic Library,即GNU高精度算术运算库),它是一个开源的高精度运算库,其中不但有普通的整数.实数.浮点数的高精度运算,还有 ...

  5. WP SyntaxHighlighter 初探

    继上篇文章发布后,我随即去网上找了下博客园.CSDN他们用的高亮工具,果然都是用的别人的,SyntaxHighlighter.去官网上看了下,很强大,包含各种经典配色以及多语言.要想在wordpres ...

  6. MySQL注射绕过技巧

    本次对以前注入的一些总结. 总有在注入的时候发现有waf或者对参数过滤了  ~~  做个文章记录下思路吧 ①.通过greatest函数绕过不能使用大小于符号的情况 我们在猜解单个字符时 通常会判断字符 ...

  7. OpenAPI安全防护

    1,开放API可能存在的数据安全问题 (1)数据窃取 通常体现为:钓鱼网站,拦截,伪装,截包 (2)数据篡改 中间被拦截,以代理的方式拦截数据,修改数据 (3)数据泄露 爬虫抓取核心数据 2,解决数据 ...

  8. redis配置参数简介

    redis配置查看方式: 1.redis的安装目录查看redis.conf 2.登陆redis客户端,使用 config get xx命令. 比如:查看所有的配置: config get * [roo ...

  9. maven构建jar包

    1.执行可执行的class,代码内需要有入口main方法 2.通过mvn package来构建jar包 3.使用java -jar test.jar来执行jar包 https://www.cnblog ...

  10. 关于JAVA_HOME, CLASSPATH和PATH的设置

    http://bbs.csdn.net/topics/120079565 1.PATH,这个是给WINDOWS操作系统用的,告诉命令行里,执行的命令行工具在那里,比如java,javac这都是命令行工 ...