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),
);

More detail

[Functional Programming] Async IO Functor的更多相关文章

  1. Functional Programming without Lambda - Part 2 Lifting, Functor, Monad

    Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...

  2. Beginning Scala study note(4) Functional Programming in Scala

    1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...

  3. Async IO

    I was recently reading a series on “Write Sequential Non-Blocking IO Code With Fibers in NodeJS” by  ...

  4. 关于函数式编程(Functional Programming)

    初学函数式编程,相信很多程序员兄弟们对于这个名字熟悉又陌生.函数,对于程序员来说并不陌生,编程对于程序员来说也并不陌生,但是函数式编程语言(Functional Programming languag ...

  5. [Functional Programming] Function signature

    It is really important to understand function signature in functional programming. The the code exam ...

  6. JavaScript Functional Programming

    JavaScript Functional Programming JavaScript 函数式编程 anonymous function https://en.wikipedia.org/wiki/ ...

  7. 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 ...

  8. 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 ...

  9. Functional programming

    In computer science, functional programming is a programming paradigm, a style of building the struc ...

随机推荐

  1. 洛谷——P2683 小岛

    P2683 小岛 题目背景 西伯利亚北部的寒地,坐落着由 N 个小岛组成的岛屿群,我们把这些小岛依次编号为 1 到 N . 题目描述 起初,岛屿之间没有任何的航线.后来随着交通的发展,逐渐出现了一些连 ...

  2. 【LeetCode two_pointer】11. Container With Most Water

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...

  3. Unity Shader 之 渲染流水线

    Unity Shader 之渲染流水线 什么是渲染流水线 一个渲染流程分成3个步骤: 应用阶段(Application stage) 几何阶段(Geometry stage) 光栅化阶段(Raster ...

  4. 常见http错误码

    一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 详细分解: 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 ...

  5. 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)

    2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1572  Solved: 7 ...

  6. 【lct】poj2763 Housewife Wind

    题意:给你一棵树,边带权,支持两种操作:修改某条边的权值:查询两点之间的最短路. lct主要实现单点修改和路径和. 修改x结点的值只需将x Splay到其所在辅助树的根,然后修改其值,再maintai ...

  7. win7环境下一次浅谈栈溢出

    在我们的生活中,存在的许许多多的漏洞,下面像大家介绍的就是平时比较常见的栈溢出漏洞的实践过程. 下面,我们用一个非常简单的例子来让大家对栈溢出漏洞有个直观的认识. 这是一个简单的密码验证程序,但因为代 ...

  8. JNI介绍

    JNI是在学习Android HAL时必须要面临一个知识点,如果你不了解它的机制,不了解它的使用方式,你会被本地代码绕的晕头转向,JNI作为一个中间语言的翻译官在运行Java代码的Android中有着 ...

  9. Java并发(九):重入锁 ReentrantLock

    先做总结: 1.为什么要用ReentrantLock? (1)ReentrantLock与synchronized具有相同的功能和内存语义: (2)synchronized是重量级锁,性能不好.Ree ...

  10. [转]STRUTS2中的OGNL

    OGNL表达式是(Object-Graph Navigation Language)是对象图形化导航语言.OGNL是一个开源的项目,struts2中默认使用OGNL表达式语言来显示数据.与serlve ...