Рассмотрим упрощенный тип foldr
.
foldr :: (a -> b -> b) -> b -> [a] -> b
Это гораздо более общий вопрос, чем требуется, поскольку вы имеете дело со всеми автомобилями.Это означает, что для поиска наибольшего Car
с foldr
типом становится
foldr :: (Car -> Car -> Car) -> Car -> [Car] -> Car
Первый аргумент - это функция, которая выбирает между двумя машинами.В вашем случае вы хотите max
, потому что его тип
max :: Ord a => a -> a -> a
становится
max :: Car -> Car -> Car
и точно соответствует.
Второй аргумент foldr
называетсяz
для нуля.Это семя для процесса складывания.Для этого вы также можете использовать первый элемент вашего списка, полученный с помощью head
.
Аргумент list типа [Car]
- это, очевидно, список, максимум которого вы хотите вычислить.Вы можете передать весь список, но заголовок уже считается аргументом z
.Лучше было бы tail list
.
Учитывая следующий список (после изменения Car
для удаления tupleForm
и получения Show
экземпляра)
cars = [ Car "A" 1 2, Car "B" 3 4, Car "C" 10 10 ]
, находя максимум с помощью foldr
- это
λ> foldr max (head cars) (tail cars)
Car {registration = "C", hour = 10, minute = 10}
Обратите внимание, что это приложение foldr
эквивалентно maximum
, но вы не обязаны верить мне на слово.Добавление
import Test.QuickCheck
в начало исходного файла, а затем
prop_max :: [Car] -> Property
prop_max l =
not (null l) ==>
maximum l == foldr max (head l) (tail l)
instance Arbitrary Car where
arbitrary = do
r <- oneof $ map return ["Apple","Orange","Banana"]
h <- choose (0,23)
m <- choose (0,59)
return (Car r h m)
дает больше уверенности в утверждении.
λ> quickCheck prop_max
+++ OK, passed 100 tests.