排序包含 Maybe Time.Posix 的对象列表

Sorting List of Objects Containing Maybe Time.Posix

我有一个自定义类型列表,我想根据 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 时间排序,所需位置没有任何值。

但是,对于可能 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

有没有办法让我的函数类型对齐以对此类数据进行排序?或者,我应该重新考虑我的方法吗?

我在 https://ellie-app.com/8dp2qD6fDzBa1

创建了一个工作示例

您的 posMay 函数属于 Maybe a -> Maybe a -> Order 类型,因此它不期望 .time,它是 {id:Int,time:Maybe Posix} -> Maybe Posix.

类型的函数

相反,您可以创建一个在 posMayList.sortWith 之间填充的不同函数,它看起来像这样:List.sortWith (\a b -> posMay a.time b.time)

如果您希望能够将 getter 函数传递给 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