While hunting for a bug, deep in some Haskell code, I found minimum used on a tuple. The code was expecting the smallest value to be returned. This took me a long time to debug. Can anyone explain why minimum behaves as it does with tuples? This feels like an easy mistake to make.
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> minimum [0,2]
0
Prelude> minimum [2,0]
0
Prelude> minimum (0,2)
2
Prelude> minimum (2,0)
0
Prelude>
>Solution :
A 2-tuple is an instance of the Foldable typeclass with [src]:
instance Foldable ((,) a) where foldMap f (_, y) = f y foldr f z (_, y) = f y z length _ = 1 null _ = False
It thus is an instance of Foldable in the sense that it is a collection of one element: the second one. This thus means that minimum on a 2-tuple will always return the second item.
Whether it was a good idea to make a 2-tuple an instance of Foldable has some discussion since a lot of operations like sum, minimum, length, all work as if it is a collection with a single element. length for example returns 1 for a 2-tuple.
It however makes sense that minimum will not work on a 2-tuple. In that case for minimum :: (Foldable f, Ord a) => f a -> a, and hence it works with f ~ (,) b, hence the signature for the 2-tuple is Ord a => (b, a) -> a. It thus works with 2-tuples where the two items can have different types, hence retrieving the minimum of the two is impossible, since the type constraint does not allow to compare the two items at all.