使用fp-ts。我有一个数组的选项
const arrayofKeys: Option<Array<K>>, 和一个记录的选择
const record: Option<Record<K,V>>我想选择Ks与Array交叉的记录的V值,并将结果放在一个选项中。
在兰达:R.pick(arrayOfKeys, record)
如何使用fp-ts或fp-ts生态系统中的其他包来解决这个问题?
发布于 2022-02-18 14:42:50
我个人会避免Ramda等人,因为在我的经验中,他们不是很好的类型。下面是一种纯粹的fp-ts方法(Str.fromNumber来自于fp std,通常被替换):
declare const arrayOfKeyNums: Option<Array<number>>
const arrayOfKeys = pipe(arrayOfKeyNums, O.map(A.map(Str.fromNumber)))
declare const record: Option<Record<string, number>>
const keyIntersectedVals: O.Option<Array<number>> = pipe(
sequenceT(O.Apply)(arrayOfKeys, record),
O.map(([ks, rec]) =>
pipe(
rec,
R.foldMapWithIndex(Str.Ord)(A.getMonoid<number>())((k, v) =>
A.elem(Str.Eq)(k)(ks) ? [v] : [],
),
),
),
)由于需要传递类型化实例,这有点冗长。从好的方面来说,类型类型实例的使用意味着可以对其进行微不足道的更新,以支持任何值类型,包括任何给定Eq的非原始类型。
下面是body在Haskell中的样子,以便进行比较,在这里,不需要传递类型实例:
keyIntersectedVals :: Maybe [Int]
keyIntersectedVals = uncurry (M.foldMapWithKey . intersectedToList) <$> sequenceT (mkeys, mmap)
where intersectedToList ks k v
| k `elem` ks = [v]
| otherwise = []例如,给定键O.some(["a", "c"])和记录O.some({ a: 123, b: 456, c: 789 }),我们得到O.some([123, 789])。
发布于 2022-01-25 22:55:29
Ramda的lift提升了一些值上的函数,以处理这些值的容器。因此,只要fp的lift (pick)支持FantasyLand应用规范,那么FantasyLand应用很可能会做你想做的事情。
const {of} = folktale.maybe
const {lift, pick} = R
const keys = of (['k', 'e', 'y', 's']) // Maybe (['k', 'e', 'y', 's'])
const record = of ({s: 1, k: 2, y: 3, b: 4, l: 5, u: 6, e: 7}) // Maybe ({s: 1, k: 2, ...})
console .log (lift (pick) (keys, record) .toString())<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/folktale/2.0.0/folktale.min.js"></script>
发布于 2022-10-24 01:43:43
这是traverseArray的一个很好的用例,它是traverse的优化版本。您还可以使用"Do notation“和apS来获得一个非常干净的一元管道。如果这些操作中的任何一个返回一个None,则整个流将提前终止(这是一个好消息!)
另外,lookup是一个非常方便的函数,类似于Ramda/Lodash中的get,但它返回一个选项。记录模块和数组模块都导出此函数的版本。
declare const arrayofKeys: O.Option<Array<string>>
declare const record: O.Option<Record<string, number>>
export const result: O.Option<ReadonlyArray<number>> = pipe(
O.Do,
O.apS('keys', arrayofKeys),
O.apS('rec', record),
O.chain(({ keys, rec }) =>
pipe(
keys,
O.traverseArray(key => pipe(rec, R.lookup(key)))
)
)
)所使用的职能:
https://stackoverflow.com/questions/70855573
复制相似问题