在 fp-ts 中,如何组合 2 个(或更多)Ord 实例
In fp-ts, how to compose 2 (or more) Ord instances
假设我有一个字符串列表,我想先按字符串长度对它们进行排序,然后再按字母顺序排序(因此列表中具有相同长度的字符串按字母顺序排序)。
我已经有 ordString
可用于按字母顺序排序。我可以为字符串长度创建自己的 Ord
实例:
import * as S from 'fp-ts/string'
import * as N from 'fp-ts/number'
import * as Ord from 'fp-ts/Ord'
const ordString = S.Ord
const ordStringLength = pipe(N.Ord, Ord.contramap((s: string) => s.length))
如果我想使用这些 Ord
对我的列表进行排序,我可以调用 A.sort
两次,但这似乎很浪费:
import * as A from 'fp-ts/Array'
const sorted = pipe(listOfStrings, A.sort(ordString), A.sort(ordStringLength))
有什么方法可以将 ordString
和 ordStringLength
实例组合成一个实例,可以在对 A.sort
的单次调用中使用?
(这是一个人为的例子来证明我的问题;实际上排序更复杂,可能涉及组合多个 Ord
s)
Ord
有一个Monoid
实例,可以用来做你想做的事;也就是说,先用一个 Ord
下单,然后再用另一个
fp-ts
docs
中有一个很好的例子
简而言之,你应该可以做到
import { sort } from 'fp-ts/Array'
import { getMonoid } from 'fp-ts/Ord'
import { concatAll } from 'fp-ts/Monoid'
const M = getMonoid<string>
const byBothOrds = concatAll(M)([ordString, ordStringLength])
const sorted = sort(byBothOrds)(listOfStrings)
如您所问,如何向其中添加额外的 Ord
应该是相当明显的。
假设我有一个字符串列表,我想先按字符串长度对它们进行排序,然后再按字母顺序排序(因此列表中具有相同长度的字符串按字母顺序排序)。
我已经有 ordString
可用于按字母顺序排序。我可以为字符串长度创建自己的 Ord
实例:
import * as S from 'fp-ts/string'
import * as N from 'fp-ts/number'
import * as Ord from 'fp-ts/Ord'
const ordString = S.Ord
const ordStringLength = pipe(N.Ord, Ord.contramap((s: string) => s.length))
如果我想使用这些 Ord
对我的列表进行排序,我可以调用 A.sort
两次,但这似乎很浪费:
import * as A from 'fp-ts/Array'
const sorted = pipe(listOfStrings, A.sort(ordString), A.sort(ordStringLength))
有什么方法可以将 ordString
和 ordStringLength
实例组合成一个实例,可以在对 A.sort
的单次调用中使用?
(这是一个人为的例子来证明我的问题;实际上排序更复杂,可能涉及组合多个 Ord
s)
Ord
有一个Monoid
实例,可以用来做你想做的事;也就是说,先用一个 Ord
下单,然后再用另一个
fp-ts
docs
简而言之,你应该可以做到
import { sort } from 'fp-ts/Array'
import { getMonoid } from 'fp-ts/Ord'
import { concatAll } from 'fp-ts/Monoid'
const M = getMonoid<string>
const byBothOrds = concatAll(M)([ordString, ordStringLength])
const sorted = sort(byBothOrds)(listOfStrings)
如您所问,如何向其中添加额外的 Ord
应该是相当明显的。