В fp-ts, как составить 2 (или более) Экземпляры Ord

#typescript #functional-programming #fp-ts

Вопрос:

Допустим, у меня есть список строк, и я хочу отсортировать их сначала по длине строки, а затем по алфавиту (поэтому строки в списке с одинаковой длиной сортируются в алфавитном порядке).

У меня уже есть 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 s для сортировки моего списка, я могу вызвать A.sort дважды, но это кажется расточительным:

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

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

Есть ли способ, которым я могу объединить ordString ordStringLength экземпляры and в один экземпляр, который можно использовать в одном вызове to A.sort ?

(это надуманный пример, демонстрирующий мой вопрос; на самом деле порядок более сложный и может включать объединение нескольких Ord экземпляров)

Комментарии:

1. Я не уверен, потому что я не fp-ts пользователь, но я вижу, что Ord у него есть экземпляр полугруппы, который, вероятно, вам нужен

2. Я думаю, что это ответ. Теперь просто нужно выяснить, как построить соответствующую полугруппу

Ответ №1:

Ord имеет Monoid экземпляр, который можно использовать для выполнения того, что вы хотите; то есть сначала упорядочить с одним Ord , затем с другим.

В fp-ts документах есть довольно хороший пример

короче говоря, вы должны быть в состоянии сделать

 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 s к этому, как вы просили.

Комментарии:

1. есть ли хорошее руководство для fp-ts? Насколько я понял, чтобы изучить fp-ts, вам нужно прочитать исходный код: (

2. Честно говоря, я мог и должен был ссылаться на документы, а не на исходный код

3. Спасибо. Я пытаюсь изучить fp-ts, иногда он выглядит совершенно нечитаемым, по крайней мере, для меня

4. Неплохо. Я действительно пошел с Ord.getSemigroup<string>().concat(ordStringLength, ordString) тем, что, кажется, делает свое дело.

5. Для пояснения: Ord является классом типа и, следовательно, не может быть экземпляром другого. Единственное отношение между классами типов — это подкласс / суперкласс. Но Ordering у типа данных есть Monoid экземпляр. Ordering это просто оболочка типа вокруг -1/0/1 компаратора.