如何在Haskell中提取列表最大元素并保留剩余列表原有顺序
Haskell提取列表最大元素并保留剩余列表顺序问题
我是Haskell的新手,想要从给定的List中提取最大元素,最终得到最大元素x和不包含x的剩余列表xs,可假设列表中的元素都是唯一的。
我想要实现的函数类型大致如下:
maxElement :: (Ord b) => (a -> b) -> [a] -> (a, [a])
值得注意的是,函数的第一个入参是将元素转换为可比较形式的函数,另外该函数是非全函数,传入空List时会运行失败。
我目前的实现方案无法保留剩余列表的元素顺序,比如输入[5, 2, 4, 6]时,它返回的是(6, [2, 4, 5]),而非我期望的(6, [5, 2, 4])。另外我觉得应该存在更简洁的实现方案,以下是我当前的代码:
compareElement :: (Ord b) => (a -> b) -> a -> (b, (a, [a])) -> (b, (a, [a])) compareElement p x (s, (t, ts)) | s' > s = (s', (x, t:ts)) | otherwise = (s, (t, x:ts)) where s' = p x maxElement :: (Ord b) => (a -> b) -> [a] -> (a, [a]) maxElement p (t:ts) = snd . foldr (compareElement p) (p t, (t, [])) $ ts
更新
感谢@Ismor的回答和@chi的评论帮助,我更新了实现版本,现在对结果很满意,代码如下:
maxElement :: (Ord b) => (a -> b) -> [a] -> Maybe (b, a, [a], [a]) maxElement p = let f x Nothing = Just (p x, x, [], [x]) f x (Just (s, m, xs, ys)) | s' > s = Just (s', x, ys, x:ys) | otherwise = Just (s, m, x:xs, x:ys) where s' = p x in foldr f Nothing
当输入列表为空时返回Nothing,否则返回Maybe (_, x, xs, _)。我可以再写一个符合最初预期类型的包装函数来调用该maxElement,但当前的实现我觉得也没问题。
内容的提问来源于stack exchange,提问作者Lando-L
相关产品推荐
相关产品推荐

