Сортировка списка объектов, содержащих может быть Time.Posix - PullRequest
2 голосов
/ 05 марта 2020

У меня есть список пользовательских типов, которые я хотел бы отсортировать по одному атрибуту типа Maybe Time.Posix. Читая документы, я пришел к выводу, что я должен использовать List.sortWith, поскольку ни значения Maybe, ни Time.Posix не равны comparable. Я написал набор функций для подготовки значений, чтобы они были сопоставимы. Однако я сталкиваюсь с проблемой извлечения значений из типов в списке.

Вот функции:

maybeCompare : (a -> a -> Order) -> Maybe a -> Maybe a -> Order
maybeCompare f a b =
    case a of
        Just some_a ->
            case b of
                Just some_b ->
                    f some_a some_b
                Nothing ->
                    GT
        Nothing ->
            LT

posixCompare : Time.Posix -> Time.Posix -> Order
posixCompare a b = compare (posixToMillis(a)) (posixToMillis(b))

posMay = maybeCompare (posixCompare)

, которые я комбинирую и использую следующим образом:

List.sortWith (posMay .time) objList

Для данных, которые выглядят так:

obj1 = {id=1,time= Just time1}
obj2 = {id=2,time= Just time2}
obj3 = {id=3,time= Just time3}
obj4 = {id=4,time= Just time4}
obj5 = {id=5,time= Nothing}

objList = obj1 :: obj2 :: obj3 :: obj4 :: obj5 :: []

Теперь этот подход работает для списка, подобного этому List (Maybe Time.Posix). Под этим подразумевается, что я получаю ожидаемый вывод, список сортируется по времени Posix со значениями Nothing в нужном месте.

Однако для списка типов, где Maybe Time.Posix является одним из значения Я получаю эту ошибку (одно из многих, но я думаю, что это источник):

List.sortWith (posMay .time) objList
                       ^^^^^
This .time field access function has type:

    { b | time : a } -> a

But `posMay` needs the 1st argument to be:

    Maybe Time.Posix

Есть ли способ выровнять типы моих функций для сортировки данных такого рода? Или я должен переосмыслить свой подход?

1 Ответ

2 голосов
/ 05 марта 2020

Я создал рабочий пример на https://ellie-app.com/8dp2qD6fDzBa1

Ваша функция posMay имеет тип Maybe a -> Maybe a -> Order, поэтому она не ожидает .time, что является Функция типа {id:Int,time:Maybe Posix} -> Maybe Posix.

Вместо этого вы можете создать другую функцию, которая переключается между posMay и List.sortWith, которая будет выглядеть следующим образом: List.sortWith (\a b -> posMay a.time b.time)

Если вы хотите чтобы иметь возможность передать функцию получения в posMay, вы можете переписать ее, чтобы принять эту функцию:

posMay getter a b =
    maybeCompare posixCompare (getter a) (getter b)

Затем вы можете использовать ее следующим образом: List.sortWith (posMay .time) (или List.sortWith (posMay identity) для List (Maybe Posix). Версия, которая работает следующим образом: https://ellie-app.com/8dp7gm3qthka1

...