[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 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
apmethod
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的更多相关文章
- [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, ...
- UCF Local Programming Contest 2016 J题(二分+bfs)
题目链接如下: https://nanti.jisuanke.com/t/43321 思路: 显然我们要采用二分的方法来寻找答案,给定一个高度如果能确定在这个高度时是否可以安全到达终点,那我们就可以很 ...
- Programming | 中/ 英文词频统计(MATLAB实现)
一.英文词频统计 英文词频统计很简单,只需借助split断句,再统计即可. 完整MATLAB代码: function wordcount %思路:中文词频统计涉及到对"词语"的判断 ...
- Coursera Algorithms Programming Assignment 4: 8 Puzzle (100分)
题目原文:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html 题目要求:设计一个程序解决8 puzzle问题以及该问题的推广 ...
- Coursera Algorithms Programming Assignment 3: Pattern Recognition (100分)
题目原文详见http://coursera.cs.princeton.edu/algs4/assignments/collinear.html 程序的主要目的是寻找n个points中的line seg ...
- The 2019 Asia Nanchang First Round Online Programming Contest C. Hello 2019(动态dp)
题意:要找到一个字符串里面存在子序列9102 而不存在8102 输出最小修改次数 思路:对于单次询问 我们可以直接区间dpOn求出最小修改次数 但是对于多次询问 我在大部分题解看到的解释一般是用线段树 ...
- Functional Programming 资料收集
书籍: Functional Programming for Java Developers SICP(Structure and Interpretation of Computer Program ...
- Adaptive AUTOSAR 学习笔记 3 - AP 背景、技术及特征(中文翻译)
本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本.本文从AUTOSAR_EXP_PlatformDesign.pdf开始,一边学习,一边顺带着翻译一 ...
- windows下gVim(Vi/vim)基本使用
Vim 是一个Linux 平台上功能非常强大的编辑器,他是早年的Vi 编辑器的加强版.这个gVim 是windows 版的,并且有了标准的windows 风格的图形界面,所以叫g(graphical) ...
随机推荐
- 2017/11/9 Leetcode 日记
2017/11/9 Leetcode 日记 566. Reshape the Matrix In MATLAB, there is a very useful function called 'res ...
- pair 对组
pair 对组 c++ 基础 2016-05-10 19:42 154人阅读 评论(0) 收藏 举报 分类: 头文件的函数精粹(12) 版权声明:本文为博主原创文章,未经博主允许不得转载. 与关联 ...
- Codeforces 798D
这两天后缀数组整多了整点有意思的,随机算法. 题意给你两个数组,让你求一个排列使得这个排列对应的两个数组前n/2+1个数之和的二倍大于每个序列总和. 下面先贴下这题正解 二维贪心,按a从大到小排,把第 ...
- 【多重背包小小的优化(。・∀・)ノ゙】BZOJ1531-[POI2005]Bank notes
[题目大意] Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,..., bn. 但是每种硬币有数量限制,现在我们想要凑出 ...
- 【主席树】BZOJ3932-[CQOI2015]任务查询系统
[题目大意] 超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi.询问,第Xi秒正在运行的 ...
- 树形DP--codevs 1380 没有上司的舞会
codevs 1380 没有上司的舞会 变式题目:给定一棵树每个点有一个点权,求一个独立集使得点权和最大,树上的独立集指的是选取树上的点,使尽量多的点不直接相连 时间限制: 1 s 空间限制: 1 ...
- noip200705统计数字
试题描述: 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出 ...
- redis配置参数简介
redis配置查看方式: 1.redis的安装目录查看redis.conf 2.登陆redis客户端,使用 config get xx命令. 比如:查看所有的配置: config get * [roo ...
- iOS开源项目大全
UI界面类项目: Panoramagl —— 720全景展示 Panorama viewer library for iPhone, iPad and iPod touch MBProgressHUD ...
- Two PWM outputs from MCU combine to form a monotonic 16-bits DAC
http://www.edn.com/design/analog/4329365/Combine-two-8-bit-outputs-to-make-one-16-bit-DAC