Doing weird things with types.
Hello All, I'm trying to create a generic function (*) using classes. I've been playing with ghc extensions but haven't found what I need yet. class HasTimes a b c where (*) :: a -> b -> c This doesn't work because it can't figure out what the return types are for a general expression a*(b*c). This kinda makes sense since someone could overload HasTimes Float Float Int and HasTimes Float Float Float. What about: class HasTimes a b where (*) :: a -> b -> c This would sort of imply that c is the only possible result of a (*) for types a and b. But I'm pretty sure this functionality hasn't been implemented. Why is this important? I'm trying to reduce ugliness of code using the following library: data Matrix = Matrix ((Float,Float),(Float,Float)) data HVec = HVec Float Float data VVec = VVec Float Float idMatrix = Matrix ((1.0,0.0),(0.0,1.0)) vhVecMult (VVec a b) (HVec c d) = Matrix ((a*c,a*d),(b*c,b*d)) matMult (Matrix ((a,b),(c,d))) (Matrix ((e,f),(g,h))) = Matrix (((a*e+b*g),(a*f+b*h)),((c*e+d*g),(c*f+d*h))) matVVecMult (Matrix ((c,d),(e,f))) (VVec a b) = VVec (a*c + b*d) (a*e + b*f) hVecMatMult (HVec a b) (Matrix ((c,d),(e,f))) = HVec (c*c+b*e) (a*d+b*f) vVecMinus (VVec a b) (VVec c d) = VVec (a-c) (b-d) vVecPlus (VVec a b) (VVec c d) = VVec (a+c) (b+d) matMinus (Matrix ((a,b),(c,d))) (Matrix ((e,f),(g,h))) = Matrix ((a-e,b-f),(c-g,d-h)) hvVecMult (HVec a b) (VVec c d) = a*c + b*d scalHVecMult :: Float -> HVec -> HVec scalHVecMult i (HVec a b ) = HVec (i*a) (i*b) Thanks, David J. Sankel
You should look at functional dependencies. They allow you to write things like: class HasTimes a b c | a b -> c where (*) :: a -> b -> c this means "a and b determine c", which is more or less what you want. This, especially as related to numeric operations, has been discussed a lot on this list; it's probably worth reading up. On Thu, 6 Nov 2003, David Sankel wrote:
Hello All,
I'm trying to create a generic function (*) using classes. I've been playing with ghc extensions but haven't found what I need yet.
class HasTimes a b c where (*) :: a -> b -> c
This doesn't work because it can't figure out what the return types are for a general expression a*(b*c). This kinda makes sense since someone could overload HasTimes Float Float Int and HasTimes Float Float Float.
What about:
class HasTimes a b where (*) :: a -> b -> c
This would sort of imply that c is the only possible result of a (*) for types a and b. But I'm pretty sure this functionality hasn't been implemented.
Why is this important? I'm trying to reduce ugliness of code using the following library:
data Matrix = Matrix ((Float,Float),(Float,Float)) data HVec = HVec Float Float data VVec = VVec Float Float
idMatrix = Matrix ((1.0,0.0),(0.0,1.0))
vhVecMult (VVec a b) (HVec c d) = Matrix ((a*c,a*d),(b*c,b*d))
matMult (Matrix ((a,b),(c,d))) (Matrix ((e,f),(g,h))) = Matrix (((a*e+b*g),(a*f+b*h)),((c*e+d*g),(c*f+d*h)))
matVVecMult (Matrix ((c,d),(e,f))) (VVec a b) = VVec (a*c + b*d) (a*e + b*f)
hVecMatMult (HVec a b) (Matrix ((c,d),(e,f))) = HVec (c*c+b*e) (a*d+b*f)
vVecMinus (VVec a b) (VVec c d) = VVec (a-c) (b-d)
vVecPlus (VVec a b) (VVec c d) = VVec (a+c) (b+d)
matMinus (Matrix ((a,b),(c,d))) (Matrix ((e,f),(g,h))) = Matrix ((a-e,b-f),(c-g,d-h))
hvVecMult (HVec a b) (VVec c d) = a*c + b*d
scalHVecMult :: Float -> HVec -> HVec scalHVecMult i (HVec a b ) = HVec (i*a) (i*b)
Thanks,
David J. Sankel
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
-- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume
participants (2)
-
David Sankel -
Hal Daume III