In Haskell, if you have a "family" of types (say, N-by-N-element matrices, for some values of N), and a parallel family of "related" types (say, N-element vectors, for the same values of N), and an operation that requires one specific type from each family (say, multiplying an N-by-N-element matrix and an N-element column vector), is it then possible to declare a type class for that operation?
For this specific example, I imagine it would look something like this:
class MatrixNxN m where
--| Multiplication of two N-by-N-element matrices
mmul :: Num a => m a -> m a -> m a
--| Multiplication of an N-by-N-element matrix and an N-element column vector
vmul :: Num a => m a -> v a -> v a
I don't know how to constrain the type v
, however. Is it possible to do something like this?
Please note that I welcome both answers to the general question of declaring a type class of multiple, related types, as well as answers to the specific question of declaring a type class for matrix-vector multiplication. In my specific case, there is only a small, known set of values of N (2, 3, and 4), but I'm generally interested in understanding what is possible to encode in Haskell's type system.
EDIT: I implemented this using MultiParamTypeClasses
and FunctionalDependencies
as suggested by Gabriel Gonzalez and MFlamer below. This is what the relevant bits of my implementation ended up looking like:
class MatrixVectorMultiplication m v | m -> v, v -> m where
vmul :: Num a => m a -> v a -> v a
data Matrix3x3 a = ...
data Vector3 a = ...
instance MatrixVectorMultiplication Matrix3x3 Vector3 where
vmul = ...
This is the type signature of vmul
, on its own and partially applied:
vmul :: (Num a, MatrixVectorMultiplication m v) => m a -> v a -> v a
(`vmul` v) :: Matrix3x3 Integer -> Vector3 Integer
(m `vmul`) :: Vector3 Integer -> Vector3 Integer
I find this all very elegant. Thanks for the answers! :)