Le *_*Moi 5 javascript functional-programming ramda.js
我对Ramda和函数式编程非常陌生,并尝试使用Ramda重写脚本,但不确定如何以一种干净的方式处理Ramda的错误。这就是我所拥有的,没有人有任何关于如何使用Ramda以功能方式重写它的指针吗?
const targetColumnIndexes = targetColumns.map(h => {
if (header.indexOf(h) == -1) {
throw new Error(`Target Column Name not found in CSV header column: ${h}`)
}
return header.indexOf(h)
})
Run Code Online (Sandbox Code Playgroud)
为了参考,这些是的值header和targetColumns
const header = [ 'CurrencyCode', 'Name', 'CountryCode' ]
const targetColumns = [ 'CurrencyCode', 'Name' ]
Run Code Online (Sandbox Code Playgroud)
所以我需要:
-1正如customcommander所说的,有一个很好的理由是,函数编程不能使这种抛出异常的样式变得容易:这很难推理。
“您的功能返回了什么?”
“一个号码。”
“总是?”
“是的,好吧,除非抛出异常。”
“它返回什么?”
“那不是。”
“那么它返回数字还是什么都不返回?”
“大概吧。”
“嗯。”
函数编程中最常见的操作之一是组成两个函数。但这仅在一个函数的输出与其后继输入匹配时才有效。如果第一个可能引发异常,这将很困难。
为了解决这个问题,FP世界使用捕获失败概念的类型。您可能已经看过有关Maybe类型的讨论,该类型处理的可能是null。另一个常见的错误是Either(有时为Result),对于错误情况和成功情况,它们分别具有两个子类型(分别Left和Rightfor Either或Errorand和Okfor)Result。在这些类型中,捕获的第一个错误被捕获并向下传递给任何需要它的人,而成功案例仍在继续处理中。(还有Validation捕获错误列表的类型。)
这些类型有许多实现。有关一些建议,请参见幻想世界列表。
Ramda曾经有自己的一组此类类型,但已放弃维护它。我们经常为此推荐民间故事和圣所。但是,即使Ramda的旧实现也应该做到。这个版本使用了Folktale,data.either因为它是我所了解的更好的版本,但是更高版本的Folktale则用代替了它Result。
以下代码块显示了如何使用Eithers处理失败的概念,特别是如何使用R.sequence来将数组Eithers转换为Either保持数组。如果输入包含任何Left,则输出仅为Left。如果全部为Rights,则输出为一个Right包含其值的数组。这样,我们可以将所有列名称转换为Eithers,以捕获值或错误,然后将它们组合为单个结果。
需要注意的是,这里没有抛出异常。我们的职能将正确组成。故障的概念封装在类型中。
const header = [ 'CurrencyCode', 'Name', 'CountryCode' ]
const getIndices = (header) => (targetColumns) =>
map((h, idx = header.indexOf(h)) => idx > -1
? Right(idx)
: Left(`Target Column Name not found in CSV header column: ${h}`)
)(targetColumns)
const getTargetIndices = getIndices(header)
// ----------
const goodIndices = getTargetIndices(['CurrencyCode', 'Name'])
console.log('============================================')
console.log(map(i => i.toString(), goodIndices)) //~> [Right(0), Right(1)]
console.log(map(i => i.isLeft, goodIndices)) //~> [false, false]
console.log(map(i => i.isRight, goodIndices)) //~> [true, true]
console.log(map(i => i.value, goodIndices)) //~> [0, 1]
console.log('--------------------------------------------')
const allGoods = sequence(of, goodIndices)
console.log(allGoods.toString()) //~> Right([0, 1])
console.log(allGoods.isLeft) //~> false
console.log(allGoods.isRight) //~> true
console.log(allGoods.value) //~> [0, 1]
console.log('============================================')
//----------
const badIndices = getTargetIndices(['CurrencyCode', 'Name', 'FooBar'])
console.log('============================================')
console.log(map(i => i.toString(), badIndices)) //~> [Right(0), Right(1), Left('Target Column Name not found in CSV header column: FooBar')
console.log(map(i => i.isLeft, badIndices)) //~> [false, false, true]
console.log(map(i => i.isRight, badIndices)) //~> [true, true, false]
console.log(map(i => i.value, badIndices)) //~> [0, 1, 'Target Column Name not found in CSV header column: FooBar']
console.log('--------------------------------------------')
const allBads = sequence(of, badIndices)
console.log(allBads.toString()) //~> Left('Target Column Name not found in CSV header column: FooBar')
console.log(allBads.isLeft) //~> true
console.log(allBads.isRight) //~> false
console.log(allBads.value) //~> 'Target Column Name not found in CSV header column: FooBar'
console.log('============================================')Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper {height: 100% !important}Run Code Online (Sandbox Code Playgroud)
<script src="//bundle.run/ramda@0.26.1"></script>
<!--script src="//bundle.run/ramda-fantasy@0.8.0"></script-->
<script src="//bundle.run/data.either@1.5.2"></script>
<script>
const {map, includes, sequence} = ramda
const Either = data_either;
const {Left, Right, of} = Either
</script>Run Code Online (Sandbox Code Playgroud)
对我来说,主要要点是,诸如goodIndices和的值本身badIndices是有用的。如果我们想对它们进行更多处理,我们可以map对它们进行简单处理。请注意例如
map(n => n * n, Right(5)) //=> Right(25)
map(n => n * n, Left('oops')) //=> Left('oops'))
Run Code Online (Sandbox Code Playgroud)
因此,我们的错误将任其独立,我们的成功将得到进一步处理。
map(map(n => n + 1), badIndices)
//=> [Right(1), Right(2), Left('Target Column Name not found in CSV header column: FooBar')]
Run Code Online (Sandbox Code Playgroud)
这就是这些类型的全部含义。
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |