Прежде всего, ваша подпись типа невозможна; чтение 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