[英]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.