为什么用ap减少选项数组会导致None



我尝试这样做是为了学习。但我无法让它发挥作用(这是一个很大的惊喜,因为你正在阅读:(

算法:

  • 输入有效/无效对象的混合列表
  • 从每个对象中提取所需的属性(或null(
  • 转换为选项列表
  • 通过使用对聚合类型进行操作的函数来减少选项列表

我无法通过优雅地提升sumAggregates来让类型工作,所以我尝试使用pipe, ap。但我想看看我们如何正确地提升sumAggregates以用于减少。

请注意,我的目标不是以不同的方式获得正确的结果,而是了解为什么我的实现失败了。

type Actionable = {
action?: string
}
type Aggregate = {
allowed: number,
blocked: number
}
const emptyAggregate: Aggregate = {
allowed: 0,
blocked: 0
}
const list: Actionable[] = [ { action: 'block'}, { }, { action: 'block'}, { }, { action: 'allow'}]
const extractAction = (a: Actionable) => a.action
const stringToAggregator = (str: string): Aggregate => {
return {
allowed: str === 'allow' ? 1 : 0,
blocked: str === 'block' ? 1 : 0,
}
}
const sumAggregates = (a: Aggregate) => (b: Aggregate): Aggregate => {
return {
allowed: a.allowed + b.allowed,
blocked: b.blocked + b.blocked,
}
}
const totals: O.Option<Aggregate> = pipe(
list,
A.map(extractAction),
A.map(O.fromNullable),
A.map(O.map(stringToAggregator)),
A.reduce(
O.some(emptyAggregate),
(a: O.Option<Aggregate>, b: O.Option<Aggregate>) => {
return pipe(O.of(sumAggregates), O.ap(a), O.ap(b))
}
)
)

返回None而不是some({allowed: 1, blocked: 2})

您最终得到None,因为reduce中列表中的一个元素是None,并且您将该None传递给reducer中的O.ap

看看这里Optionap的定义。当提供None时,提升的计算不被调用,并且ap的结果因此变成None。那么,对于以下最基本的计算,你会期望结果是什么呢?

import * as O from 'fp-ts/Option'
import {identity, pipe} from 'fp-ts/function'
const result: O.Option<number> = pipe(
O.some(identity),
O.ap(O.none),
)

应该是None,对吧?这就是Option的应用/应用实例所具有的效果。因此,在reduce函数中,一旦遇到None并将其传递给ap,累加器将以None的情况结束,并且不能执行sumAggregates的进一步应用。

相关内容

  • 没有找到相关文章

最新更新