The problem is that the compiler does not know how to select the correct instance, given what it knows. If you try something like
vectorA `dot` vectorA
the compiler is looking for the correct dot , knowing that its type must be dot :: Vector -> Vector -> c0 . Unfortunately, this is simply not enough information in itself - c0 can be anything, and the compiler never assumes that just because it has only one instance, it must be correct (this is due to the assumption of an open world --- there may be another instance that the compiler has not yet seen, so he prefers to simply throw an error). You can get away from it by explicitly telling the compiler what the result should be
vectorA `dot` vectorB :: Double
but this is tedious and most likely fails badly with numeric types, since often these types are also common. For example, which Num instance is used here?
(vectorA `dot` vectorB) + 3
We know this Double , but the compiler cannot prove it.
One solution is to use type families, as @AndrewC suggests in a comment. I really highly recommend this. Another solution that you will see in the wild is functional dependencies. They are written like this:
class InnerProductSpace abc | ab -> c where dot :: a -> b -> c
and translate to promise the compiler: "Know a and b enough information to uniquely identify c ." The compiler keeps you informed, and this will not allow you to write instances that contradict this promise.
instance InnerProductSpace Vector Vector Double where dot (Vector a) (Vector b) = (head a * head b) instance InnerProductSpace Vector Vector Float where dot (Vector a) (Vector b) = (head a * head b) --- /Users/tel/tmp/foo.hs:10:10: Functional dependencies conflict between instance declarations: instance InnerProductSpace Vector Vector Double -- Defined at /Users/tel/tmp/foo.hs:10:10 instance InnerProductSpace Vector Vector Float -- Defined at /Users/tel/tmp/foo.hs:13:10
But the promise gives the compiler enough information to resolve Double in the previous example.
Main*> (Vector [1,2,3]) `dot` (Vector [2,3,4]) + 3.0 5