Search code examples
haskellsyntaxfold

how to correctly apply the foldr function


Im attempting to find the max element of a list, where the elements are a data type created by myself, using a fold instead of doing it recursively. However i end up with an error "couldn't match type". As im fairly new to haskell im having trouble seeing the problem and wish to know how to correctly apply the foldr function.

My attempt at obtaining the largest elements looks like this:

-- (foldr comparison (head list) (tail list))

which won't compile.

i have included the datatype and its instances for Eq and Ord, and i've also included the comparison function.

 -- Car data type

 data Car = Car {registration :: String,
                    hour :: Integer, 
                  minute :: Integer, 
               tupleForm :: PTime
           }

-- Equality comparison between Car data types
-- reqiures equality by registration number, hours and minutes

instance Eq Car where 
     (Car r1 h1 m1 _) == (Car r2 h2 m2 _) = (r1 == r2) && (((h1*60)+m1) == 
((h2*60)+m2))

-- Order comparison between Car data types
-- Compares time of two Cars , hours and minutes 

instance Ord Car where 
     compare (Car _ h1 m1 _) (Car _ h2 m2 _) = compare ((h1*60)+m1) 
     ((h2*60)+m2)  


-- Returns the larger Car
comparison :: (Car,Car) -> Car
comparison(car1,car2) = if(car1 > car2) then car1 else car2

My expected result after folding the list of Car is to obtain the 'largest car' ,which basically means the car with the largest time. But I end up with a compilation error due to faulty type.


Solution

  • The problem is the type and definition of comparison.

    First, the type should be Car -> Car -> Car: you take two Car values and return the bigger one.

    Second, your definition of comparison tries to match a single argument as a tuple, rather than two separate arguments. Drop the parentheses and the comma.

    comparison :: Car -> Car -> Car
    comparison car1 car2 = if car1 > car2 then car1 else car2
    

    (Of course, comparison is just max restricted to Car rather than Ord a => a.

    comparison :: Car -> Car -> Car
    comparison = max
    

    And, as Robin Zigmond points out, foldr comparison x is basically maximum for an appropriate value x.)