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. MAC OS 10.11.1虚拟机免费下载已安装Xcode7图片后有下载地址

    MAC OS 10.11.1虚拟机免费下载已安装Xcode7图片后有下载地址 注意:已经下载过MAC OS 10.10.5虚拟机免费下载(可安装Xcode7)链接:http://www.cnblogs ...

  2. .net中session的使用

    什么是Session? Session即会话,是指一个用户在一段时间内对某一个站点的一次访问. Session对象在.NET中对应HttpSessionState类,表示"会话状态" ...

  3. KMP的小结

    http://www.cnblogs.com/kuangbin/archive/2012/08/14/2638803.html 如果有哪一天不记得模板了就去看看大神的 .  非常清晰易懂.

  4. centos 7 源码包安装、卸载nginx

    1.源码包安装之前,首页安装依赖包 yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre ...

  5. ElasticSearch学习笔记--2、ES相关配置

    1.配置文件 ES的配置文件位置:config/elasticsearch.yml可以直接搜索elasticsearch.yml 2.配置远程api访问 network.host: 192.168.1 ...

  6. hdu 3294 manacher 求回文串

    感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...

  7. bzoj 3298: [USACO 2011Open]cow checkers -- 数学

    3298: [USACO 2011Open]cow checkers Time Limit: 10 Sec  Memory Limit: 128 MB Description 一天,Besssie准备 ...

  8. Windows下Apache2.2+PHP5安装步骤

    Windows下Apache2.2+PHP5安装 初学者在学习PHP的时候可能都会遇到安装Apache和PHP不成功的问题,于是很多开发者便选择了集成包,一键安装好Apache+PHP+MySQL.但 ...

  9. asp.net 将repeater上数据导出到excel

    1,首先得到一个DataTable public DataTable GetTable(string sql) { SqlConnnection con=new SqlConnection(Confi ...

  10. ruby 状态转移

    0. 引言       昨天遇到一个问题,就是关于对象状态转移的问题,我姑且这样命名吧.简要描述一下就是:对于一个人,他有进食,帮助他人,恋爱等功能,但是这些功能是有先后顺序的,对于刚出生的人,他要先 ...