[Functional Programming] Async IO Functor
We will see a peculiar example of a pure function. This function contained a side-effect, but we dubbed it pure by wrapping its action in another function. Here's another example of this:
// getFromStorage :: String -> (_ -> String)
const getFromStorage = key => () => localStorage[key];
'localStorage' is a side effect, but we wrap into a function call, so what 'getFromStorage' return is not a value but a function. And this returned function is waiting to be called, before calling, we can do all kind of function mapping of composion on it, that's the beautity.
Let's see how to define a IO functor for this side-effect code:
class IO {
static of(x) {
return new IO(() => x);
}
constructor(fn) {
this.$value = fn;
}
map(fn) {
return new IO(compose(fn, this.$value));
}
inspect() {
return `IO(${this.$value})`;
}
}
IO will take a function as input.
Example of IO:
( Note: the reuslt shown in comment is not actual result, the actual result is wrapped in {$value: [Function]}, just for now, we show the result which should be in the end.)
// ioWindow :: IO Window
const ioWindow = new IO(() => window); ioWindow.map(win => win.innerWidth);
// IO(1430) ioWindow
.map(prop('location'))
.map(prop('href'))
.map(split('/'));
// IO(['http:', '', 'localhost:8000', 'blog', 'posts'])
There is some library already define the IO functor for us, we don't need to write one for our own, for example, Async from Crocks.js, or Data.Task from Folktale.
Here we are using 'Data.Task' as an example:
// -- Node readFile example ------------------------------------------
const fs = require('fs');
// readFile :: String -> Task Error String
const readFile = filename => new Task((reject, result) => {
fs.readFile(filename, (err, data) => (err ? reject(err) : result(data)));
});
readFile('metamorphosis').map(split('\n')).map(head);
// Task('One morning, as Gregor Samsa was waking up from anxious dreams, he discovered that
// in bed he had been changed into a monstrous verminous bug.')
// -- jQuery getJSON example -----------------------------------------
// getJSON :: String -> {} -> Task Error JSON
const getJSON = curry((url, params) => new Task((reject, result) => {
$.getJSON(url, params, result).fail(reject);
}));
getJSON('/video', { id: }).map(prop('title'));
// Task('Family Matters ep 15')
// -- Default Minimal Context ----------------------------------------
// We can put normal, non futuristic values inside as well
Task.of().map(three => three + );
// Task(4)
To run the Task, we need to call 'fork(rej, res)':
// -- Pure application -------------------------------------------------
// blogPage :: Posts -> HTML
const blogPage = Handlebars.compile(blogTemplate); // renderPage :: Posts -> HTML
const renderPage = compose(blogPage, sortBy(prop('date'))); // blog :: Params -> Task Error HTML
const blog = compose(map(renderPage), getJSON('/posts')); // -- Impure calling code ----------------------------------------------
blog({}).fork(
error => $('#error').html(error.message),
page => $('#main').html(page),
);
Example of Either & IO:
// validateUser :: (User -> Either String ()) -> User -> Either String User
const validateUser = curry((validate, user) => validate(user).map(_ => user)); // save :: User -> IO User
const save = user => new IO(() => ({ ...user, saved: true })); const validateName = ({ name }) => (name.length >
? Either.of(null)
: left('Your name need to be > 3')
); const saveAndWelcome = compose(map(showWelcome), save); const register = compose(
either(IO.of, saveAndWelcome),
validateUser(validateName),
);
[Functional Programming] Async IO Functor的更多相关文章
- Functional Programming without Lambda - Part 2 Lifting, Functor, Monad
Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...
- Beginning Scala study note(4) Functional Programming in Scala
1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...
- Async IO
I was recently reading a series on “Write Sequential Non-Blocking IO Code With Fibers in NodeJS” by ...
- 关于函数式编程(Functional Programming)
初学函数式编程,相信很多程序员兄弟们对于这个名字熟悉又陌生.函数,对于程序员来说并不陌生,编程对于程序员来说也并不陌生,但是函数式编程语言(Functional Programming languag ...
- [Functional Programming] Function signature
It is really important to understand function signature in functional programming. The the code exam ...
- JavaScript Functional Programming
JavaScript Functional Programming JavaScript 函数式编程 anonymous function https://en.wikipedia.org/wiki/ ...
- Functional Programming without Lambda - Part 1 Functional Composition
Functions in Java Prior to the introduction of Lambda Expressions feature in version 8, Java had lon ...
- a primary example for Functional programming in javascript
background In pursuit of a real-world application, let’s say we need an e-commerce web applicationfo ...
- Functional programming
In computer science, functional programming is a programming paradigm, a style of building the struc ...
随机推荐
- 在eclipse中安装TestNG
https://www.cnblogs.com/baixiaozheng/p/4989856.html 1.可借助Eclipse的Marketplace来安装TestNG Eclipse插件 a.打开 ...
- Knockout.js(四):自定义绑定
除了内嵌的绑定,还可以创建一些自定义绑定,封装复杂的逻辑或行为. 注册绑定 添加子属性到ko.bindingHandlers来注册绑定: ko.bindingHandlers.yourBindingN ...
- django使用mongodb建表
1.安装mongodb的py模块包 pip install mongoengine 同时安装了mongoengine.pymongo 2.在项目配置文件settings.py中配置 from mong ...
- 【HDU 6020】 MG loves apple (乱搞?)
MG loves apple Accepts: 20 Submissions: 693 Time Limit: 3000/1500 MS (Java/Others) Memory Limit: ...
- PHP 笔记——基础
一.PHP 简介 1. PHP是什么 PHP:Hypertext Preprocessor,即超文本预处理器. PHP是一种跨平台.服务器端.可嵌入HTML文件的脚本语言. 嵌入了PHP代码的HTML ...
- 【贪心】【高精度】zoj3987 Numbers
题意:给你一个数n,让你找m个非负整数,使得它们的和为n,并且按位或起来以后的值最小化.输出这个值. 从高位到低位枚举最终结果,假设当前是第i位,如果m*(2^i-1)<n的话,那么说明这一位如 ...
- 【HDU】6410:序列期望
序列期望 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- bzoj 3784
第三道点分治. 首先找到黄学长的题解,他叫我参考XXX的题解,但已经没有了,然后找到另一个博客的简略题解,没看懂,最后看了一个晚上黄学长代码,写出来然后,写暴力都拍了小数据,但居然超时,....然后改 ...
- ZOJ 3213 Beautiful Meadow 简单路径 插头DP
简单路径的题目,其实就是在状态后面多记了有多少个独立插头. 分类讨论独立插头: 1.只存在上插头或者左插头,可以选择作为独立插头. 2.都不存在上插头和左插头,选择作为独立插头的同时要标号为新的连通块 ...
- mysql存储过程导入表
运用存储过程,把用户表一数据导入用户表二 DELIMITER @@ CREATE PROCEDURE imp_to_user2() BEGIN – 声明一个标志done, 用来判断游标是否遍历完成 D ...