基于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)) |
问题分析与修复
两次报错的核心原因:
- 首次报错是语法错误:错误用函数组合符
.代替字段访问的.,导致参数解析混乱。 - 修改后的报错是参数传递错误:
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
相关产品推荐
相关产品推荐

