Ramda 中简单的 Point-free 函数
Simple Point-free functions in Ramda
我还在学习 Ramda,经常无法将看似简单的 lamda 函数转换为无点纯 Ramda 函数。这是一个简单的例子:
export const consoleTap = arg =>
R.compose(
R.tap,
R.curryN(2, console[arg])
);
export const errorTap = consoleTap("error");
export const logTap = consoleTap("log");
// example usage
R.map(logTap("Value"))([1, 2]) // Results in printing "Value 1" "Value 2"
这些函数运行良好,我什至为它们编写了测试。我只是觉得 consoleTap 可以无意义地编写,只是有些东西我没有正确地看到或理解。函数可以重写吗?
我想不出一个看起来不太复杂的无积分版本。我觉得你的已经很不错了
我唯一的建议是将事情分开:将日志记录与 tap
分开。您可以单独重复使用 "prefixed" 版本的日志记录:
const logWith = (method, prefix) => curryN(2, console[method])(prefix);
const log = logWith('log', 'INFO: ');
const error = logWith('error', 'ERR: ');
log(10); // INFO: 10
error(10); // ERR: 10
和 tap
:
const logTap = tap(logWith('error', 'ERR: '));
logTap(10);
// ERR: 10
// => 10
您遇到的问题是由于 R.tap
不是可变参数。
// tap is a unary function
const log = R.tap(console.log);
// logs only `1`
log(1, 2, 3, 4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>
所以你不能 log('Value is, 1)
,一个解决方法是将 tap 的参数与 R.unapply
分组,然后通过 R.apply
将它们应用回记录器
一个简单的解决方案可能是在向记录器提供前缀后调用 R.tap
:
const logger = R.pipe(
R.prop(R.__, console),
R.curryN(2),
);
const error = logger('error');
const log = logger('log');
const result = R.map(
R.tap(log('value is')),
)([1, 2]);
// tap didn't alter any item inside the functor.
console.log('result is', result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>
我还在学习 Ramda,经常无法将看似简单的 lamda 函数转换为无点纯 Ramda 函数。这是一个简单的例子:
export const consoleTap = arg =>
R.compose(
R.tap,
R.curryN(2, console[arg])
);
export const errorTap = consoleTap("error");
export const logTap = consoleTap("log");
// example usage
R.map(logTap("Value"))([1, 2]) // Results in printing "Value 1" "Value 2"
这些函数运行良好,我什至为它们编写了测试。我只是觉得 consoleTap 可以无意义地编写,只是有些东西我没有正确地看到或理解。函数可以重写吗?
我想不出一个看起来不太复杂的无积分版本。我觉得你的已经很不错了
我唯一的建议是将事情分开:将日志记录与 tap
分开。您可以单独重复使用 "prefixed" 版本的日志记录:
const logWith = (method, prefix) => curryN(2, console[method])(prefix);
const log = logWith('log', 'INFO: ');
const error = logWith('error', 'ERR: ');
log(10); // INFO: 10
error(10); // ERR: 10
和 tap
:
const logTap = tap(logWith('error', 'ERR: '));
logTap(10);
// ERR: 10
// => 10
您遇到的问题是由于 R.tap
不是可变参数。
// tap is a unary function
const log = R.tap(console.log);
// logs only `1`
log(1, 2, 3, 4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>
所以你不能 log('Value is, 1)
,一个解决方法是将 tap 的参数与 R.unapply
分组,然后通过 R.apply
一个简单的解决方案可能是在向记录器提供前缀后调用 R.tap
:
const logger = R.pipe(
R.prop(R.__, console),
R.curryN(2),
);
const error = logger('error');
const log = logger('log');
const result = R.map(
R.tap(log('value is')),
)([1, 2]);
// tap didn't alter any item inside the functor.
console.log('result is', result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>