繁体   English   中英

如何使用值对列表[MVar a]进行排序?

[英]How to sort a list [MVar a] using a values?

如何对[MVar a]列表进行排序? 使用a作为元素进行排序比较。 例如:

sortList :: [MVar Int] -> [MVar Int]

我不能不打破其他思路而思考。

更新:我需要对列表进行排序,因为我想实现像MVar这样的引用计数,并始终返回引用最少的那个。 就像是:

getLeastUsed :: [MVar Int] -> MVar Int
getLeastUsed = head . sortList

并在线程中我想增加'Int'。

更新:答案中我注意到,严格签名需要IO,因为MVar

首先,您的类型签名是不可能的; 读取MVar并不是参照透明的(希望应该很明显-这就是他们的目的 !)。 这有两个结果:

  • 您的排序功能必须返回IO操作
  • 该列表将根据读取每个MVar时看到的值进行排序。 它不仅可能在您使用列表时无效,而且可能会在更改过程中途发生变化,以使第一个值在读取最后一个值之前已过期。

前者是不可避免的,并且假设后者对于您的目的是可以接受的,那么您基本上可以执行@hammar演示的操作。

但是,由于排序很快就会过时,并且您似乎对最小元素最感兴趣,因此您可能会发现这样的事情更直接有用,因为否则排序几乎没有用处:

import Control.Applicative
import Data.List
import Data.Ord

leastUsed :: [MVar Int] -> IO (MVar Int)
leastUsed vars = fst . minimumBy (comparing snd) . zip vars <$> mapM readMVar vars

最简单的方法可能是做一个decorate-sort-unecorate,您首先要读出MVar的所有当前值,然后使用这些值作为键进行排序。

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

sortList :: [MVar Int] -> IO [MVar Int]
sortList vars = do
    currentValues <- mapM readMVar vars
    return . map snd . sortBy (comparing fst) $ zip currentValues vars

请注意,由于MVars的值自读取以来可能已更改,因此结果列表可能未完全排序。 但是,如果您对此感到担心,则可能应该对整个列表使用单个MVar。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM