[Functional Programming] From simple implementation to Currying to Partial Application
一身转战三千里,一剑曾当百万师。这篇文章主要讲述[Functional Programming] From simple implementation to Currying to Partial Application相关的知识,希望能为你提供帮助。
Let‘s say we want to write a most simple implementation ‘avg‘ function:
const avg = list => { let sum = 0; for(let i = 0; i < list.length; i++) { sum += list[i] } return sum / list.length }
Basiclly, the ‘avg‘ function doing two things:
- Calculate sum
- Divide sum / length
In the following examples, We want to bring in two libarays which are commonly used in FP. One is Ramda, another one is Crocks.
Currying:
First, we want to write ‘sum‘ and ‘devide‘ functions by ourselves:
const { curry, reduce, compose } = require("crocks"); const R = require("ramda"); const sum = reduce(R.add, 0); // divideByLen :: [Number] -> Number -> Number const divideByLen = curry( compose( R.flip(R.divide), R.length ) );
‘sum‘ is simple, using ‘reduce‘ from Crocks, you can also write JS reduce, doesn‘t matter.
What we need to explain is ‘divideByLen‘ function.
- Why ‘curry‘?
divideByLen([1,2,3], sum([1,2,3])) divideByLen([1,2,3])(sum([1,2,3]))
[Notice] You need to bring in ‘curry‘ from Crocks, it is more flexable.
- Why ‘flip‘?
Bring all together:
const avg = list => compose( divideByLen(list), sum )(list);
【[Functional Programming] From simple implementation to Currying to Partial Application】We notice that, we have to pass ‘list‘ to both Sum(list) and divideByLen(list). The code looks not so good. Whenever you are facing the situation, you need to pass the same arguement to two functions in parallel. You can consider to using ‘Partial Application‘.
Partial Application:
// Ramda
const avg = R.converge(R.divide, [R.sum, R.length]);
We are using ‘Ramda‘s converge‘ function, bascilly you have pass in a data, the data will be passed to R.sum(data) & R.length(data), the return results of those two functions, will be passed to R.divide(resOfSum, resOfLength).
//Crocks:
const { curry, fanout, merge, compose } = require("crocks"); const avg = compose( merge(R.divide), fanout(R.sum, R.length) );
We are using the Pair ADT, the data will be passed to R.sum(data) & R.length(data) thought ‘fanout‘ function, it returns Pair(resOfSum, resOfLength).
Then we use ‘merge‘, it works with Pair ADT, we merge two results by R.divide(resOfSum, resOfLength).
推荐阅读
- Delphi通过AppendMenu和DeleteMenu在系统菜单中添加删除菜单项
- Ambari(Provide ability to apply single patches on top of RU release)
- 适合精致女孩使用的APP软件 不容错过的精彩人生
- AndroidCardView
- Android Programming
- Android 6.0 默认关闭定位和GPS,开启后默认选省电
- android开发注意几点
- Jupyter Notebook入门指南
- 了解持续集成和持续部署