Итак, я случайно написал ответ Haskell на Scala вопрос недавно. Поскольку я был хорошо знаком с Haskell, решение пришло ко мне довольно легко:
myMaxBy :: (a -> a -> Ordering) -> [a] -> [a]
myMaxBy _ [] = undefined
myMaxBy f (x:xs) = foldr step [x] xs
where step y acc@(z:_) = case f y z of
GT -> [y]
EQ -> y:acc
LT -> acc
Затем кто-то напомнил мне, что это вопрос Scala. Я решил преобразовать свой код в Scala и после долгих мучений согласился:
(List(xs.head) /: xs.tail) { (acc, y) =>
y compare acc.head match {
1 => List(y)
0 => y :: acc
-1 => acc
}
}
Но я не мог, хоть убей, заставить систему типов Scala подчиняться моей воле и обобщать это в функции, где xs
и compare
являются входами (в идеале каррированные входы с компаратором в первую очередь). Хотя это, безусловно, связано с моим общим незнанием Scala, я также слегка виню сложную (хотя и очень мощную) систему типов Scala. Не могли бы вы подержать за руку и объяснить, как я могу превратить это в обобщенную функцию с сигнатурой типа, подобной эквиваленту в Haskell? (Прочтите: в общем, как .) Пожалуйста, также продемонстрируйте использование, если оно сложнее, чем myMaxBy (myCompare) (someList)
.