【问题标题】:In fp-ts, how to compose 2 (or more) Ord instances在 fp-ts 中,如何组合 2 个(或更多)Ord 实例
【发布时间】:2021-12-10 19:13:25
【问题描述】:

假设我有一个字符串列表,我想先按字符串长度然后按字母顺序对它们进行排序(因此列表中具有相同长度的字符串按字母顺序排序)。

我已经有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))

如果我想使用这些Ords 对我的列表进行排序,我可以调用A.sort 两次,但这似乎很浪费:

import * as A from 'fp-ts/Array'

const sorted = pipe(listOfStrings, A.sort(ordString), A.sort(ordStringLength))

有没有办法可以将ordStringordStringLength 实例组合成一个实例,可以在对A.sort 的一次调用中使用?

(这是一个人为的例子来证明我的问题;实际上排序更复杂,可能涉及组合几个Ords)

【问题讨论】:

  • 我不确定,因为我不是fp-ts 用户,但我看到Ord 有一个半组实例,这可能是你想要的
  • 我认为这就是答案。现在只需要弄清楚如何构建适当的半群

标签: typescript functional-programming fp-ts


【解决方案1】:

Ord 有一个Monoid 实例,可以用来做你想做的事;也就是说,先订购一个Ord,然后再订购另一个。

fp-tsdocs中有一个很好的例子

简而言之,你应该可以做到

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)

按照您的要求,如何在其中添加额外的Ords 应该是相当明显的。

【讨论】:

  • fp-ts 有没有好的指南?据我了解,为了学习 fp-ts 你需要阅读源代码:(
  • 公平地说,我可以而且应该链接到文档,而不是源代码
  • 谢谢。我正在尝试学习 fp-ts,有时它看起来很不可读,至少对我来说是这样
  • 不错。我实际上选择了Ord.getSemigroup&lt;string&gt;().concat(ordStringLength, ordString),这似乎可以解决问题。
  • 为了澄清:Ord 是一个类型类,因此不能是另一个类型的实例。类型类之间的唯一关系是子类/超类。但是Ordering 数据类型有一个Monoid 实例。 Ordering 只是 -1/0/1 比较器的类型包装器。
猜你喜欢
  • 2022-01-07
  • 2023-03-10
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 2023-02-01
  • 2021-08-07
  • 1970-01-01
  • 2022-08-14
相关资源
最近更新 更多