Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding maximum element in a list of tuples

Tags:

haskell

I am a complete beginner in Haskell. I have a list of tuples that I'm using in Haskell: the structure is like this [(a,b),(c,d),(e,f),(g,h)]

What I want is to return the maximum element in this tuple according to the second value: So if the list of tuples is [(4,8),(9,10),(15,16),(10,4)], I want the maximum element to be (15,16).

But I have no idea how to do this. This is my attempt so far,

maximum' ::  (Ord a) => (Num a) => [(a,b)] -> a  
maximum' [] = error "maximum of empty list"  
maximum' [(x,y)] = -1
maximum' (x:xs)   
  | snd x > snd(xs !! maxTail) = 0
  | otherwise = maxTail  
  where maxTail = maximum' xs + 1

And I get this error message which makes no sense for me:

newjo.hs:23:25:
Could not deduce (a ~ Int)
from the context (Ord a, Num a)
  bound by the type signature for
             maximum' :: (Ord a, Num a) => [(a, b)] -> a
  at newjo.hs:19:14-47
  `a' is a rigid type variable bound by
      the type signature for maximum' :: (Ord a, Num a) => [(a, b)] -> a
      at newjo.hs:19:14
In the second argument of `(!!)', namely `maxTail'
In the first argument of `snd', namely `(xs !! maxTail)'
In the second argument of `(>)', namely `snd (xs !! maxTail)'`

I need some help on how to do this.

like image 662
Manav Dutta Avatar asked Aug 08 '13 05:08

Manav Dutta


2 Answers

The idiomatic way would be to use maximumBy (comparing snd).

The a ~ Int message means that for some reason Haskell infers that a must be an Int, but the type signature does not limit it to Ints. As Amos notes in the comments and GHC tells you with its source location, this is because you're using it as the second argument of !!, which is an Int.

like image 190
icktoofay Avatar answered Sep 22 '22 01:09

icktoofay


An idiomatic way using the libraries is to use maximumBy.

maximumBy :: (a -> a -> Ordering) -> [a] -> a

Then all is left is to define the function of type a -> a ->Ordering so it knows how to order the elements. The usual way to construct Ordering objects is to use

compare :: (Ord a) => a -> a -> Ordering
like image 36
luqui Avatar answered Sep 22 '22 01:09

luqui