ImmutableJS vs Ramda或ImmutableJS + Ramda-它们可以一起使用吗

时间:2019-04-05 14:35:43

标签: functional-programming immutable.js ramda.js

我正在探索这两个库,对我来说ImmutableJS具有(大部分)不可变的数据结构,而Ramda具有FP的瑞士军刀工具。

当我在Google上搜索时,看到RamdaImmutableJS之类的文章相互推荐,但乍一看,至少对我来说,它们是相辅相成的。

我可以想象React应用中的所有数据结构都是ImmutableJSListSetMapRecord)但是使用Ramda来组成函数,对ImmutableJS集合进行转换等,或者当我错过诸如uniq之类的某些功能时。

您怎么看?这是明智的做法吗?

2 个答案:

答案 0 :(得分:3)

可以一起使用吗?不顺利或无缝。

按照目前的情况,这很可能是一种方法,它将使您至少遇到一些困难,并且很可能会遇到很多困难。原因是不可变的结构与ramda的功能不兼容。您也许可以创建包装器或互操作程序来修补此功能,但这似乎是一个相当大的项目。

This issue进行了更详细的介绍,并包括了List.

这样的不可变js的潜在替代方案。

下面是一个非常小的例子,说明缺乏互操作性是一个问题:

const { Map } = Immutable;
const { path } = R;

const standardObject = {a: 1, b: 2, c: 3};
const map1 = Immutable.Map(standardObject);

const getA = path(['a']);

const result = getA(map1);
const defaultResult = getA(standardObject);

console.dir(result);
console.dir(defaultResult);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>

您大概可以将转换转换为您在ramda中所做的工作;这似乎是解决问题的最简单方法,尽管它确实意味着您将代码与不可变数据结构紧密联系在一起。可能是这样的:

const { Map } = Immutable;
const { path, pipe } = R;

const standardObject = {a: 1, b: 2, c: 3};
const map1 = Immutable.Map(standardObject);

const toStandard = map => map.toObject()

const getA = pipe(
  toStandard,
  path(['a'])
)

const result = getA(map1)

console.dir(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>

答案 1 :(得分:0)

Ramda可以免费使用某些集成。 Ramda将其许多调用委托给数据对象。通常,如果Ramda函数的名称与Immutable方法的名称相同,则Ramda将执行集成。

这意味着您通常可以在Ramda中使用不可变列表或Map,而通常使用Array或Object。

const {Map, List} = immutable
const {map, filter, find} = ramda

const square = n => n * n
const isEven = n => n % 2 == 0

const xs = new List([1, 2, 3, 4, 5])

console.log(map(square, xs)) //=> List [1, 4, 9, 16, 25]
console.log(filter(isEven, xs)) //=> List [2, 4]
console.log(find(n => n > 3, xs)) //=> 3

const x = new Map({a: 1, b: 2, c: 3, d: 4, e: 5});

console.log(map(square, x))
//=> Map {"a" => 1, "b" => 4, "c" => 9, "d" => 16, "e" => 25}
console.log(filter(isEven, x)) //=> Map {"c" => 3, "d" => 4, "e" => 5}
<script src="https://bundle.run/ramda@0.26.1"></script>
<script src="https://bundle.run/immutable@4.0.0-rc.12"></script>

不过,目前这仅受共享名称的限制。而且并非Ramda的所有功能都以这种方式委托。

就像奥利弗·拉迪尼(Oliver Radini)提到的the issue一样,我有一些真正的兴趣,就是希望在Ramda中更轻松地与Immutable之类的工具进行进一步的集成,但是它从未跻身榜首, Ramda的贡献者中有一些真正的反对。