In this lesson we'll take some existing code and refactor it using some functions from the Ramda library, most notably, compose and converge. When we're done, we'll have taken a function with a couple of local variables and parameter references and converted it into more streamlined "point-free" or "tacit" functions.

For example, we have following function:

const R = require('ramda');

const person = {
id: ,
name: 'Joe'
}; const generateUrl = (id) => `http://img.soicalnetwork.com/avatar/${id}.png`;
const getUpdatedPerson = (person) => {
const url = generateUrl(person.id);
return R.assoc('avatar', url, person);
}
const result = getUpdatedPerson(person);

It will add a 'avatar' prop to person object.

We want to refactor the code to make it point free style, we the functions can be more reuseable and easy to understand.

First try:

//===============================================
// #1 Refactoring
//===============================================
/*
Solve the problem that when id is undefined, we need a default image
Solution: propOr('defaultValue', 'prop')
*/ const generateUrl = (id) => `http://img.soicalnetwork.com/avatar/${id}.png`;
const getUpdatedPerson = (person) => {
const url = generateUrl(R.propOr('default', 'id')(person));
return R.assoc('avatar', url, person);
}
const result = getUpdatedPerson(person);
console.log(result);

Here we use 'R.propOr', to get prop of an object and set default fallback value. This can help us prevent undefined problem.

Second try:

//===============================================
// #2 Refactoring
//===============================================
/**
* Extra a single function to get Person url.
* Solution: Here we using R.compose.
* SO getURLFromPerson is point-free function.
*/ const generateUrl = (id) => `http://img.soicalnetwork.com/avatar/${id}.png`;
const getURLFromPerson = R.compose(
generateUrl,
R.propOr('default', 'id')
);
const getUpdatedPerson = (person) => R.assoc('avatar', getURLFromPerson(person), person);
const result = getUpdatedPerson(person);
console.log(result);

Here we use 'R.compose' to make 'getURLFromPerson' as a point-free function. Notice in the function, we no longer need to pass 'person' object as a param.

Third try:

//===============================================
// #3 Refactoring
//===============================================
/**
* In getUpdatedPerson function, we still relay on the 'person' param we pass in.
* We want to make it a point-free function also.
* Solution: we can use R.converge
*/
const generateUrl = (id) => `http://img.soicalnetwork.com/avatar/${id}.png`;
const getURLFromPerson = R.compose(
generateUrl,
R.propOr('default', 'id')
);
// const getUpdatedPerson = (person) => R.assoc('avatar', getURLFromPerson(person), person);
const getUpdatedPerson = R.converge(
R.assoc('avatar'),
[
getURLFromPerson,
R.identity
]
)
const result = getUpdatedPerson(person);
console.log(result);

The old verson of 'getUpdatedPerson' relay on 'person' param, to make it as point-free function style, we can use another way 'R.converge'.

[Ramda] Refactor to Point Free Functions with Ramda using compose and converge的更多相关文章

  1. [Ramda] Curry and Uncurry Functions with Ramda

    Most of the functions offered by the ramda library are curried by default. Functions you've created ...

  2. [Ramda] Get Deeply Nested Properties Safely with Ramda's path and pathOr Functions

    In this lesson we'll see how Ramda's path and pathOr functions can be used to safely access a deeply ...

  3. [Ramda] Convert Object Methods into Composable Functions with Ramda

    In this lesson, we'll look at how we can use Ramda's invoker and constructNfunctions to take methods ...

  4. [Ramda] Refactor to a Point Free Function with Ramda's useWith Function

    Naming things is hard and arguments in generic utility functions are no exception. Making functions ...

  5. [Ramda] Refactor a Promise Chain to Function Composition using Ramda

    Promise chains can be a powerful way to handle a series of transformations to the results of an asyn ...

  6. [Ramda] Eliminate Function Arguments (Point-Free Style) with Ramda's Converge

    When doing comparisons inside of functions, you end of relying heavily on the argument passed into t ...

  7. [Ramda] Count Words in a String with Ramda's countBy and invert

    You can really unlock the power of ramda (and functional programming in general) when you combine fu ...

  8. [React] Update Component State in React With Ramda Lenses

    In this lesson, we'll refactor a React component to use Ramda lenses to update our component state. ...

  9. [Ramda] Pick and Omit Properties from Objects Using Ramda

    Sometimes you just need a subset of an object. In this lesson, we'll cover how you can accomplish th ...

随机推荐

  1. powerdesigner 连接mysql提示“connection test failed”

    powerdesigner  连接mysql提示“connection test failed”,该如何解决: 1.把64位的jdk换成32位的jdk(VM只支持32的jre) 2.系统变量:  CL ...

  2. http 500 Internal Server Error的错误 ajax请求SpringMVC后台中返回500 Internal Server Error

    使用httprequester接口测试能返回数据,但是用ajax返回json格式的时候返回报500Internal Server Error. The server encountered an in ...

  3. ArcEngine的ToolbarControl解析

    转自Love Lyre原文 ArcEngine的ToolbarControl解析 ToolbarControlClass有三个主要的接口: IToolbarControl, IToolbarContr ...

  4. StartCoroutine的使用

    StartCoroutine在unity3d的帮助中叫做协程,意思就是启动一个辅助的线程. 在C#中直接有Thread这个线程,可是在unity中有些元素是不能操作的.这个时候能够使用协程来完毕. 使 ...

  5. 2.1 Vue组件

    Vue组件 全局组件和局部组件 父子组件通讯-数据传递 父->子:通过Props传递 子->父:不允许,但vue通过子组件触发Emit来提交给子组件进行触发 Slot import Cou ...

  6. JVM route

    http://www.linuxidc.com/Linux/2013-06/86446.htm

  7. CC2530定时器使用

     定时器学习   文件夹 说明 依据数据手冊可知CC2530总共同拥有4个定时器,可是定时器2被系统占用,可用的仅仅有三个,分别为定时器1/3/4 Timer在协议栈的代码位置为hal_timer ...

  8. stm32关于.o的错误

    是因为没有加入官方库的原因,而且编译出错之后不能跳转到那里.

  9. Python中的Sets数据结构

    Python的set和其他语言类似,是一个无序不重复元素集,基本功能包括关系测试和消除重复元素.集合对象支持union(联合),intersection(交),difference(差)和sysmme ...

  10. maven 解决Cannot change version of project facet Dynamic web module to 2.5

    我们用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2.3的,而一 ...