What is applicative functor:

the ability to apply functors to each other.

For example we have tow functors: Container(2), Container(3)

// We can't do this because the numbers are bottled up.
add(Container.of(), Container.of()); // NaN

We cannot just add two functors!

Instead we should do:

const map = (fn, m) => m.map(fn);
const containerOfAdd2 = map(add(), Container.of()); // Container(5)

or

Container.of().chain(two => Container.of().map(add(two)));

Previous solution should work. but there are better way to do it:

1. ap

Container.prototype.ap = function (otherContainer) {
return otherContainer.map(this.$value);
};

As you can see, 'ap' takes a fuctor then applya map to it.

We can see ap:

Container.of().map(add).ap(Container.of()); // Container(5)

Or, we add lift 'add(2)' into Container, then apply Container(3):

Container.of(add()).ap(Container.of()); // Container(5)

Because 'add' is partially  applied in add(2), when doing '.ap(Container.of(3))', we give the rest input '3' to it.

Now, we can define applicative functor in programming language:

An applicative functor is a pointed functor with an ap method

Note the dependence on pointed.

Laws behind:

F.of(x).map(f) === F.of(f).ap(F.of(x))

Main idea is: lift 'f' (function) into Functor, then 'ap' (apply) another Functor with the value (x).

Some example:

Maybe.of(add).ap(Maybe.of()).ap(Maybe.of()) // Just(5)
Task.of(add).ap(Task.of()).ap(Task.of()) // Task(5)

Equals:

Maybe.of(add()).ap(Maybe.of()) // Just(5)
Task.of(add()).ap(Task.of()) // Task(5)

More examples:

// Http.get :: String -> Task Error HTML

const renderPage = curry((destinations, events) => { /* render page */ });

Task.of(renderPage).ap(Http.get('/destinations')).ap(Http.get('/events'));
// Task("<div>some page with dest and events</div>")
// $ :: String -> IO DOM
const $ = selector => new IO(() => document.querySelector(selector)); // getVal :: String -> IO String
const getVal = compose(map(prop('value')), $); // signIn :: String -> String -> Bool -> User
const signIn = curry((username, password, rememberMe) => { /* signing in */ }); IO.of(signIn).ap(getVal('#email')).ap(getVal('#password')).ap(IO.of(false));
// IO({ id: 3, email: 'gg@allin.com' })

----

const R = require('ramda');

class Container {
static of(x) {
return new Container(x);
} constructor(x) {
this.$value = x;
} map (fn) {
return Container.of(fn(this.$value));
} ap (functor) {
return functor.map(this.$value);
} join() {
return this.$value;
} chain(fn) {
return this.map(fn).join();
} inspect() {
return `Container(${this.$value})`;
}
} class Maybe {
get isNothing() {
return this.$value === null || this.$value === undefined;
} get isJust() {
return !this.isNothing;
} constructor(x) {
this.$value = x;
} inspect() {
return this.isNothing ? 'Nothing' : `Just(${this.$value})`;
} // ----- Pointed Maybe
static of(x) {
return new Maybe(x);
} // ----- Functor Maybe
map(fn) {
return this.isNothing ? this : Maybe.of(fn(this.$value));
} // ----- Applicative Maybe
ap(f) {
return this.isNothing ? this : f.map(this.$value);
} // ----- Monad Maybe
chain(fn) {
return this.map(fn).join();
} join() {
return this.isNothing ? this : this.$value;
} // ----- Traversable Maybe
sequence(of) {
this.traverse(of, identity);
} traverse(of, fn) {
return this.isNothing ? of(this) : fn(this.$value).map(Maybe.of);
}
} const add = a => b => a + b;
const map = (fn, m) => m.map(fn);
const notWorking = add(Container.of(2), Container.of(3));
const containerOfAdd2 = map(add(3), Container.of(2));
console.log(containerOfAdd2); // Contianer(5) const works = Container.of(2).chain(v => Container.of(3).map(add(v)));
console.log(works); // Contianer(5) const ap = Container.of(2).map(add).ap(Container.of(3));
console.log(ap) const ap2 = Container.of(add(2)).ap(Container.of(3));
console.log(Maybe.of(add).ap(Maybe.of(2)).ap(Maybe.of(3)))
console.log(Maybe.of(add(2)).ap(Maybe.of(3)))

  

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

  1. [Functional Programming] Working with two functors(Applicative Functors)-- Part2 --liftAN

    Let's examine a pointfree way to write these applicative calls. Since we know map is equal to of/ap, ...

  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. Adaptive AUTOSAR 学习笔记 3 - AP 背景、技术及特征(中文翻译)

    本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本.本文从AUTOSAR_EXP_PlatformDesign.pdf开始,一边学习,一边顺带着翻译一 ...

  9. windows下gVim(Vi/vim)基本使用

    Vim 是一个Linux 平台上功能非常强大的编辑器,他是早年的Vi 编辑器的加强版.这个gVim 是windows 版的,并且有了标准的windows 风格的图形界面,所以叫g(graphical) ...

随机推荐

  1. c++入门笔记

    对于有java基础的人来说,学习c++并不难,毕竟c++是java的前身. 何况还熟练掌握了java呢,哈哈. 安装gcc环境,照着菜鸟教程来. 开发工具ide使用vs,eclipse虽然用习惯了,这 ...

  2. jquery实用的一些方法

    做个购物车功能,需要修改下前端页面 有些实用的方法总结一下 当你想实现最基本的加减法的时候,对于转换number实用Number(str)即可 首先明确下页面的每一行是动态的,这个时候绑定事件的时候不 ...

  3. 管理openstack多region介绍与实践

    转:http://www.cnblogs.com/zhoumingang/p/5514853.html 概念介绍 所谓openstack多region,就是多套openstack共享一个keyston ...

  4. 深入理解javascript作用域系列第四篇

    前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...

  5. Ubuntu下修改ubuntu源,完成Redis Desktop Manager的安装

    原文地址: http://blog.csdn.net/u013410747/article/details/51706964 免费下载链接:http://pan.baidu.com/s/1cA3jWU ...

  6. 【BZOJ 3106】 3106: [cqoi2013]棋盘游戏 (对抗搜索)

    3106: [cqoi2013]棋盘游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 544  Solved: 233 Description 一个 ...

  7. codevs 1058 合唱队形 2004年NOIP全国联赛提高组

    1058 合唱队形 2004年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold   题目描述 Description N位同学站成一排,音 ...

  8. 「CSA49」Card Collecting Game

    「CSA49」Card Collecting Game 题目大意:有 \(n\) 种卡片,每种有 \(b_i\) 张,如果一个人集齐 \(k\) 张第 \(i\) 种卡片,那么其能获得的得分是 \(\ ...

  9. 【20181027T2】易水决【贪心+堆】

    原题:loj6035 [错解] 全肝T1了没怎么想 [正解] 一眼贪心 先考虑\(b_i=0\)怎么做 可以模拟一个正常人的思维 开一个堆,记录每个任务需要的时间(包括等待),每次从中取出一个任务,表 ...

  10. 【tarjan+拓扑】BZOJ3887-[Usaco2015 Jan]Grass Cownoisseur

    [题目大意] 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) [思路] 首先 ...