You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于UTC时间排序RequestQueue中元组的Haskell技术问题求助

对RequestQueue按Request的reqTimestamp排序的问题解决

问题背景

尝试对包含(Request, Response)元组的RequestQueue数据类型,按照Request的reqTimestamp(UTC时间)进行排序,编写的代码及报错信息如下:

初始代码

sortRequestQueueByTimestamp :: RequestQueue -> RequestQueue
sortRequestQueueByTimestamp (RequestQueue queue) = 
    RequestQueue (sortBy (\(req1, _) (req2, _) -> compare (reqTimestamp req1) (reqTimestamp req2) queue))

首次报错信息

app\main.hs:17:28: error: [GHC-83865]
    * Couldn't match expected type `Request'
                  with actual type `(b3, b0)'
    * In the pattern: (req1, _)
      In the first argument of `sortBy', namely
        `(\ (req1, _) (req2, _)
            -> compare req1 . reqTimestamp req2 . reqTimestamp)'
      In the first argument of `RequestQueue', namely
        `(sortBy
            (\ (req1, _) (req2, _)
               -> compare req1 . reqTimestamp req2 . reqTimestamp)
            queue)'
   |
17 |     RequestQueue (sortBy (\(req1, _) (req2, _) -> compare req1.reqTimestamp req2.reqTimestamp) queue)

使用的数据类型定义

data Request = Request { 
    reqId :: Int, 
    reqTimestamp :: UTCTime,
    reqOrigin :: String,
    reqData :: String 
    } deriving (Show, Eq, Ord)

data Response = Response {
    resId :: Int, 
    resTimestamp :: UTCTime,
    resDestination :: String,
    resData :: String 
    } deriving (Show, Eq, Ord)

data RequestQueue = RequestQueue {
    queue :: [(Request, Response)]
    } deriving (Show)

修改后新报错信息

app\Main.hs:16:19: error: [GHC-83865]
    * Couldn't match expected type: [(Request, Response)]
                  with actual type: [(Request, b0)] -> [(Request, b0)]
    * Probable cause: `sortBy' is applied to too few arguments
      In the first argument of `RequestQueue', namely
        `(sortBy
            (\ (req1, _) (req2, _)
               -> compare (reqTimestamp req1) (reqTimestamp req2) queue))'
      In the expression:
        RequestQueue
          (sortBy
             (\ (req1, _) (req2, _)
                -> compare (reqTimestamp req1) (reqTimestamp req2) queue))
      In an equation for `sortRequestQueueByTimestamp':
          sortRequestQueueByTimestamp (RequestQueue queue)
            = RequestQueue
                (sortBy
                   (\ (req1, _) (req2, _)
                      -> compare (reqTimestamp req1) (reqTimestamp req2) queue))
   |
16 |     RequestQueue (sortBy (\(req1, _) (req2, _) -> compare (reqTimestamp req1) (reqTimestamp req2) queue))
   |                   

问题分析与修复

两次报错的核心原因:

  1. 首次报错是语法错误:错误用函数组合符.代替字段访问的.,导致参数解析混乱。
  2. 修改后的报错是参数传递错误:sortBy需要两个参数(排序函数、待排序列表),但你把queue写到了排序函数的表达式内部,导致sortBy只收到一个参数,返回的是函数而非排序后的列表。

正确代码

import Data.List (sortBy)
import Data.Ord (comparing)

sortRequestQueueByTimestamp :: RequestQueue -> RequestQueue
sortRequestQueueByTimestamp (RequestQueue queue) = 
    RequestQueue $ sortBy (comparing (reqTimestamp . fst)) queue

或者更直白的写法:

sortRequestQueueByTimestamp (RequestQueue queue) = 
    RequestQueue $ sortBy (\(req1, _) (req2, _) -> compare (reqTimestamp req1) (reqTimestamp req2)) queue

代码解释

  • sortBy的正确调用方式是sortBy 排序函数 待排序列表,必须将queue作为第二个参数传入,而非嵌套在排序函数中。
  • comparing函数可以简化排序逻辑:它接收一个提取排序键的函数,直接返回对应的比较函数,无需手动编写compare的逻辑。
  • reqTimestamp . fst是函数组合,先取元组的第一个元素(即Request),再提取其reqTimestamp字段作为排序依据。

内容的提问来源于stack exchange,提问作者UnknownPerson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:16:16