Hi,
So I'm trying the fun-deps example from http://www.haskell.org/hawiki/FunDeps and seeing if I can use it, but I can't really get things to work the way I want. The code follows below, and the error I get if I try to multiply 10 <*> (vector 10 [0..9]) is 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])) import Array -- The elements and the size data Vec a = Vec (Array Int a) Int deriving (Show,Eq) type Matrix a = (Vec (Vec a)) class MatrixProduct a b c | a b -> c where (<*>) :: a -> b -> c instance (Num a) => MatrixProduct a (Vec a) (Vec a) where (<*>) num (Vec a s) = Vec (fmap (*num) a) s vector n elms = Vec (array (0,n-1) $ zip [0..n-1] elms) n _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
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. 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)]) _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
On 13 Apr 2006 03:27:03 -0000, [hidden email] <[hidden email]> 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? _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
Free forum by Nabble | Edit this page |