2
votes

I'm am training funtional Haskell and cannot usderstand what is wrong with this:

maxBy :: (a -> Int) -> a -> a -> a
maxBy measure a b = max (measure a) (measure b)

Here are examples how this maxBy function should work:

maxBy (*2)   3       5      ==>  5
maxBy length [1,2,3] [4,5]  ==>  [1,2,3]
maxBy head   [1,2,3] [4,5]  ==>  [4,5]

Error message is:

Couldn't match expected type ‘a’ with actual type ‘Int’ ‘a’ is a rigid type variable bound by the type signature for: maxBy :: forall a. (a -> Int) -> a -> a -> a

1
Welcome to Haskell! This subtle type disagreement is exactly the sort of thing that happens all the time in more dynamic languages and everyone thinks it's fine and no-one notices... until they get burned by it, and then they have to examine their entire program to find the contradiction. It's much easier to give the burden of spotting these contradictions to a typechecking compiler like GHC.James Brock
This is one of the cases where it really helps to comment out the type signature and get surprised by the type the compiler infers.Ingo

1 Answers

5
votes

Your function is returning measure a or measure b when you want it to return a or b.