From oleg-at-okmij.org Thu Apr 13 03:27:03 2006
Date: 13 Apr 2006 03:27:03 -0000
Message-ID: <20060413032703.26000.qmail@eeoth.pair.com>
To: haskell-cafe@haskell.org
Subject: Re: Fundeps: I feel dumb
Status: OR
Creighton Hogg wrote:
> No instance for (MatrixProduct a (Vec b) c)
> arising from use of `<*>' at :1:3-5
> Probable fix: add an instance declaration for (MatrixProduct a
> (Vec b) c)
> In the definition of `it': it = 10 <*> (vector 10 ([0 .. 9]))
Let us look at the instance
class MatrixProduct a b c | a b -> c where
(<*>) :: a -> b -> c
instance (Num a) => MatrixProduct a (Vec a) (Vec a) where
it defines what happens when multiplying a vector of some numeric type
'a' by a value _of the same_ type. Let us now look at the error
message:
> (MatrixProduct a (Vec b) c)
That is, when trying to compile your expression
10 <*> (vector 10 ([0 .. 9]))
the typechecker went looking for (MatrixProduct a (Vec b) c)
where the value and the vector have different numeric types. There is
no instance for such a general case, hence the error. It is important
to remember that the typechecker first infers the most general type
for an expression, and then tries to resolve the constraints. In your
expression,
10 <*> (vector 10 ([0 .. 9]))
we see constants 10, 10, 0, 9. Each constant has the type Num a => a.
Within the expression 0 .. 9, both 0 and 9 must be of the same type
(because [n .. m] is an abbreviation for enumFromThen n m, and
according
to the type of the latter
enumFromThen :: a -> a -> [a]
both arguments must be of the same type).
But there is nothing that says that the first occurrence of 10 must be
of the same numeric type as the occurrence of 9. So, the most general
type assignment will be (Num a => a) for 10, and (Num b => b) for 9.
Solution: either choose a specific (non-polymorphic type)
> test1 = (10::Int) <*> (vector 10 [0..9::Int])
Or tell the typechecker that those constants must be of the same type:
> test2 = let n = 10 in n <*> (vector 10 [0..(9 `asTypeOf` n)])