[Haskell-cafe] Re: Fundeps: I feel dumb

Creighton Hogg wchogg at gmail.com
Thu Apr 13 15:32:22 EDT 2006


On 13 Apr 2006 03:27:03 -0000, oleg at pobox.com <oleg at pobox.com> wrote:
>
> Creighton Hogg wrote:
>
> >     No instance for (MatrixProduct a (Vec b) c)
> >       arising from use of `<*>' at <interactive>: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.

Thank you very much for the explanation:  it makes alot of sense.
So, if one does not want to for alot of type declarations into the
code, which would be fairly awkward, is there a way to do this with
fundeps or other type extensions that will be alot prettier or is any
way of defining type classes going to run into the same problems?


More information about the Haskell-Cafe mailing list