Zhe*_*hen 1 algorithm concurrency haskell
如何对[MVar a]列表进行排序?使用a作为要在排序中进行比较的元素.例如:
sortList :: [MVar Int] -> [MVar Int]
Run Code Online (Sandbox Code Playgroud)
我不能在没有打破其他线程的情况下想办法.
更新: 我需要对列表进行排序,因为我想实现像MVar这样的引用计数,并始终返回具有最少引用的引用计数.就像是:
getLeastUsed :: [MVar Int] -> MVar Int
getLeastUsed = head . sortList
Run Code Online (Sandbox Code Playgroud)
在线程中我想增加'Int'.
更新: 由于答案,我认为rigth签名需要IO,因为MVar
首先,你的类型签名是不可能的; 阅读a 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
Run Code Online (Sandbox Code Playgroud)
最简单的方法可能是做一个decorate-sort-undecorate,你首先读出MVars的所有当前值,然后使用它们作为键进行排序.
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
Run Code Online (Sandbox Code Playgroud)
请注意,结果列表可能未完全排序,因为MVars的值自读取后可能已更改.但是,如果您关心这一点,您可能应该使用单个MVar作为整个列表.
| 归档时间: |
|
| 查看次数: |
385 次 |
| 最近记录: |