Опцион заключается в использовании пользовательской функции сравнения и minimumBy
, как прокомментировали другие. Обратите внимание, что в этом случае ваше преобразование (+5)
будет называться дважды для каждого элемента в списке (примерно). Например.
[4,3,2,1]
приводит к
compare 4 3 => compare (4+5) (3+5) => compare 9 8 => GT
compare 3 2 => compare (3+5) (2+5) => compare 8 7 => GT
compare 2 1 => compare (2+5) (1+5) => compare 8 7 => GT
(3+5),(2+5)
Обратите внимание, что вычисляются в два раза выше.
Если операция стоит дорого и просто (+5)
, может оказаться полезным использовать другой подход. Мы можем предварительно вычислить измененные значения, сохраняя при этом оригинальные из них, если мы строим список пар:
map (\x -> (expensive x, x)) [4,3,2,1]
выше, функция expensive
играет роль (+5)
в исходном коде.Затем мы можем взять минимум следующим образом:
snd $ minimumBy (comparing fst) $ map (\x -> (expensive x, x)) [4,3,2,1]
или даже
snd $ minimum $ map (\x -> (expensive x, x)) [4,3,2,1]
Последние несколько меньше общего в том, что он требует, чтобы список [4,3,2,1]
состоит из несравнимых элементов, в то время как бывший только предполагает что expensive
производит нечто сопоставимое.
Однако обратите внимание, что последнее не только вернет случайный элемент в список [4,3,2,1]
, который минимизирует expensive
, но это будет минимальный такой элемент. То есть, когда expensive x == expensive y
, функция minimum
нарушит связь, сравнивая x
и y
. Первый не дает такой гарантии.