{-# LANGUAGE UndecidableInstances #-}

module Pandora.Paradigm.Primary.Linear.Matrix where

import Pandora.Pattern.Category (($))
import Pandora.Pattern.Object.Semigroup (Semigroup ((+)))
import Pandora.Pattern.Object.Monoid (Monoid (zero))
import Pandora.Pattern.Object.Setoid (Setoid ((==)))
import Pandora.Paradigm.Primary.Linear.Vector (Vector)

newtype Matrix i j a = Matrix (Vector i (Vector j a))

instance (Semigroup a, Semigroup (Vector i a), Semigroup (Vector i (Vector j a))) => Semigroup (Matrix i j a) where
	~(Matrix Vector i (Vector j a)
x) + :: Matrix i j a -> Matrix i j a -> Matrix i j a
+ ~(Matrix Vector i (Vector j a)
y) = Vector i (Vector j a) -> Matrix i j a
forall i j a. Vector i (Vector j a) -> Matrix i j a
Matrix (Vector i (Vector j a) -> Matrix i j a)
-> Vector i (Vector j a) -> Matrix i j a
forall (m :: * -> * -> *) a b. Category m => m (m a b) (m a b)
$ Vector i (Vector j a)
x Vector i (Vector j a)
-> Vector i (Vector j a) -> Vector i (Vector j a)
forall a. Semigroup a => a -> a -> a
+ Vector i (Vector j a)
y

instance (Monoid a, Monoid (Vector i a), Monoid (Vector i (Vector j a))) => Monoid (Matrix i j a) where
	zero :: Matrix i j a
zero = Vector i (Vector j a) -> Matrix i j a
forall i j a. Vector i (Vector j a) -> Matrix i j a
Matrix Vector i (Vector j a)
forall a. Monoid a => a
zero

instance (Setoid a, Setoid (Vector i a), Setoid (Vector i (Vector j a))) => Setoid (Matrix i j a) where
	Matrix Vector i (Vector j a)
x == :: Matrix i j a -> Matrix i j a -> Boolean
== Matrix Vector i (Vector j a)
y = Vector i (Vector j a)
x Vector i (Vector j a) -> Vector i (Vector j a) -> Boolean
forall a. Setoid a => a -> a -> Boolean
== Vector i (Vector j a)
y