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. Django项目中模板标签及模板的继承与引用【网站中快速布置广告】

    Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...

  2. FastReport.Net使用:[22]地图(Map)控件

    标记有学生地区 1.在报表中放一个地图控件 将地图控件放在标题区即可,其他栏目删除. 2.双击地图控件进行地图添加. 可以再网上下载到地图数据,ESRI shapefile文件,本例中找了个省会城市地 ...

  3. 矩阵乘法<简单总结>

    原理:矩阵相乘最重要的方法是一般矩阵乘积.它只有在第一个矩阵的 行数 和第二个矩阵的 列数 相同时才可进行.若A为m×n矩阵,B为n×p矩阵,则他们的乘积AB会是一个m×p矩阵. 若A=    a   ...

  4. HDU 6141 I am your Father!(最小树形图)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6141 [题目大意] 给出一个有向图,求1点为根的最小树形图使得第n个点的直接父亲编号最小 [题解] ...

  5. 【DFS】BZOJ3522-[Poi2014]Hotel

    [题目大意] 给出一棵树,求三个节点使得它们两两之间的距离相等,问共有多少种可能性? [思路] 显然,这三个节点是关于一个中心点对称地辐射出去的. 枚举中心点,往它的各个子树跑Dfs.tmp[i]表示 ...

  6. Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D. Little Artem and Dance 模拟

    D. Little Artem and Dance 题目连接: http://www.codeforces.com/contest/669/problem/D Description Little A ...

  7. MySQL的max_user_connections拒绝连接的一次踩雷经验

    近期线上的数据遇到一个问题,最终原因为max_user_connections和max_connections的一个bug导致,具体过程如下 现象 前端页面不断的出现错误页面. 排查处理过程 按照数据 ...

  8. CentOS 6.9/7通过yum安装指定版本的Node.js

    说明:通过yum好处其实很多,环境变量不用配置,配置文件放在大家都熟悉的地方,通过rpm -ql xxx可以知道全部文件的地方等等. Node.js(8.x) 一.安装和配置 1.安装Node.js ...

  9. ted飞行器

    http://v.youku.com/v_show/id_XNTc0MTk0MzI4.html

  10. 创建Windows窗体 : WinMain() 与 WndProc()

    #include <windows.h> #include <mmsystem.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, ...