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. 洛谷P2408 不同字串个数 [后缀数组]

    题目传送门 不同字串个数 题目背景 因为NOI被虐傻了,蒟蒻的YJQ准备来学习一下字符串,于是它碰到了这样一道题: 题目描述 给你一个长为N的字符串,求不同的子串的个数 我们定义两个子串不同,当且仅当 ...

  2. bash shell 关系

    linux的bash和shell关系 shell通俗理解:把用户输入的命令翻译给操作系统. shell 是一个交互性命令解释器.shell独立于操作系统,这种设计让用户可以灵活选择适合自己的shell ...

  3. FastReport.Net使用:[21]表格(Table)控件

    对表格控件的一些常用操作 合并单元格:选择需要合并的单元格(按住Shitf多选),然后在右键菜单中选择[合并单元格].         2.删除/插入行 鼠标移到在行头,当鼠标状态变为向右的箭头时点击 ...

  4. Ubuntu 无线驱动问题

    最近一次更新系统后开机发现电脑只能连有线网络连不上无线网络.我平时都是连无线网络,没有买网线.所以查了下无线驱动相关问题资料,发现是由于更新系统造成无线网卡驱动莫名不见了.刚开始还以为是电脑将无线禁用 ...

  5. Javascript中的异步

    在C#,Java中,异步方法,通常是伴随多线程,并发等术语一起出现的,比如C#中的async方法,是运行在一个线程池线程上,并且在异步方法运行完成后,有一个回调函数通知主线程. 那么由于Javascr ...

  6. HDU 5645 DZY Loves Balls 水题

    DZY Loves Balls 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5645 Description DZY loves playing b ...

  7. HDU 5640 King's Cake GCD

    King's Cake 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5640 Description It is the king's birthd ...

  8. AJAX传递数组

    在前台中Jq代码中中用JSON.stringify()将数组转换成 JSON字符串.在后台用json_decode()将JSON字符串转换成数组. 1.JSON.stringify(value [, ...

  9. SQL Server的thread scheduling(线程调度)

      https://www.zhihu.com/question/53125711/answer/134461670 https://www.zhihu.com/question/53125711   ...

  10. [前端]使用JQuery UI Layout Plug-in布局

    引言 使用JQuery UI Layout Plug-in布局框架实现快速布局,用起来还是挺方便的,稍微研究了一下,就能上手,关于该布局框架的材料,网上也挺多的.在项目中也使用到了,不过那是前端的工作 ...