@@ -1,3 +1,4 @@
1+{-# LANGUAGE ConstraintKinds #-}
12{-# LANGUAGE AllowAmbiguousTypes #-}
23{-# LANGUAGE DataKinds #-}
34{-# LANGUAGE DerivingVia #-}
@@ -170,6 +171,17 @@ import qualified LAoP.Matrix.Internal as I
170171newtype Matrix e (cols :: Type) (rows :: Type) = M (I.Matrix e (I.Normalize cols) (I.Normalize rows))
171172 deriving (Show, Num, Eq, Ord, NFData) via (I.Matrix e (I.Normalize cols) (I.Normalize rows))
172173
174+-- | Constraint type synonyms to keep the type signatures less convoluted
175+type Countable a = KnownNat (I.Count a)
176+type CountableDimensions a b = (Countable a, Countable b)
177+type CountableN a = KnownNat (I.Count (I.Normalize a))
178+type CountableDimensionsN a b = (CountableN a, CountableN b)
179+type FromListsN e a b = I.FromLists e (I.Normalize a) (I.Normalize b)
180+type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
181+type Trivial a = I.Normalize a ~ I.Normalize (I.Normalize a)
182+type TrivialE a b = I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)
183+type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
184+
173185-- | It isn't possible to implement the 'id' function so it's
174186-- implementation is 'undefined'. However 'comp' can be and this partial
175187-- class implementation exists just to make the code more readable.
@@ -197,7 +209,7 @@ one = M . I.One
197209
198210-- | Matrix 'Junc' constructor
199211junc ::
200− (I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)) =>
212+ (TrivialE a b) =>
201213 Matrix e a rows ->
202214 Matrix e b rows ->
203215 Matrix e (Either a b) rows
@@ -206,7 +218,7 @@ junc (M a) (M b) = M (I.Junc a b)
206218infixl 3 |||
207219-- | Matrix 'Junc' constructor
208220(|||) ::
209− (I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)) =>
221+ (TrivialE a b) =>
210222 Matrix e a rows ->
211223 Matrix e b rows ->
212224 Matrix e (Either a b) rows
@@ -214,7 +226,7 @@ infixl 3 |||
214226
215227-- | Matrix 'Split' constructor
216228split ::
217− (I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)) =>
229+ (TrivialE a b) =>
218230 Matrix e cols a ->
219231 Matrix e cols b ->
220232 Matrix e cols (Either a b)
@@ -223,7 +235,7 @@ split (M a) (M b) = M (I.Split a b)
223235infixl 2 ===
224236-- | Matrix 'Split' constructor
225237(===) ::
226− (I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)) =>
238+ (TrivialE a b) =>
227239 Matrix e cols a ->
228240 Matrix e cols b ->
229241 Matrix e cols (Either a b)
@@ -233,16 +245,9 @@ infixl 2 ===
233245
234246-- | Functor instance equivalent function
235247fmapM ::
236− ( Bounded a,
237− Bounded b,
238− Enum a,
239− Enum b,
240− Eq b,
241− Num e,
242− Ord e,
243− KnownNat (I.Count (I.Normalize a)),
244− KnownNat (I.Count (I.Normalize b)),
245− I.FromLists e (I.Normalize b) (I.Normalize a)
248+ ( Liftable e a b,
249+ CountableDimensionsN a b,
250+ FromListsN e b a
246251 )
247252 =>
248253 (a -> b) -> Matrix e c a -> Matrix e c b
@@ -254,25 +259,23 @@ unitM = one 1
254259
255260-- | Applicative instance equivalent 'unit' function,
256261multM ::
257− ( KnownNat (I.Count (I.Normalize a)),
258− KnownNat (I.Count (I.Normalize b)),
259− KnownNat (I.Count (I.Normalize (a, b))),
262+ ( CountableDimensionsN a b,
263+ CountableN (a, b),
260264 Num e,
261− I.FromLists e (I.Normalize (a, b)) (I.Normalize a),
262− I.FromLists e (I.Normalize (a, b)) (I.Normalize b),
263− I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
265+ FromListsN e (a, b) a,
266+ FromListsN e (a, b) b,
267+ TrivialP a b
264268 ) => Matrix e c a -> Matrix e c b -> Matrix e c (a, b)
265−multM a b = khatri a b
266−
269+multM = khatri
267270
268271-- | Monad instance equivalent 'return' function,
269272returnM ::
270273 forall e a .
271− ( Num e,
272− Enum e,
273− Enum a,
274− I.FromLists e () (I.Normalize a),
275− KnownNat (I.Count a)
274+ ( Num e,
275+ Enum e,
276+ Enum a,
277+ FromListsN e () a,
278+ Countable a
276279 ) => a -> Matrix e One a
277280returnM a = col l
278281 where
@@ -288,23 +291,22 @@ bindM = flip comp
288291
289292-- | Build a matrix out of a list of list of elements. Throws a runtime
290293-- error if the dimensions do not match.
291−fromLists :: (I.FromLists e (I.Normalize cols) (I.Normalize rows)) => [[e]] -> Matrix e cols rows
294+fromLists :: (FromListsN e cols rows) => [[e]] -> Matrix e cols rows
292295fromLists = M . I.fromLists
293296
294297-- | Matrix builder function. Constructs a matrix provided with
295298-- a construction function.
296299matrixBuilder ::
297− (I.FromLists e (I.Normalize cols) (I.Normalize rows), KnownNat (I.Count (I.Normalize cols)), KnownNat (I.Count (I.Normalize rows))) =>
298− ((Int, Int) -> e) ->
299− Matrix e cols rows
300+ (FromListsN e cols rows, CountableDimensionsN cols rows )
301+ => ((Int, Int) -> e) -> Matrix e cols rows
300302matrixBuilder = M . I.matrixBuilder
301303
302304-- | Constructs a column vector matrix
303−col :: (I.FromLists e () (I.Normalize rows)) => [e] -> Matrix e One rows
305+col :: (FromListsN e () rows) => [e] -> Matrix e One rows
304306col = M . I.col
305307
306308-- | Constructs a row vector matrix
307−row :: (I.FromLists e (I.Normalize cols) ()) => [e] -> Matrix e cols One
309+row :: (FromListsN e cols ()) => [e] -> Matrix e cols One
308310row = M . I.row
309311
310312-- | Lifts functions to matrices with arbitrary dimensions.
@@ -312,49 +314,28 @@ row = M . I.row
312314-- NOTE: Be careful to not ask for a matrix bigger than the cardinality of
313315-- types @a@ or @b@ allows.
314316fromF ::
315− ( Bounded a,
316− Bounded b,
317− Enum a,
318− Enum b,
319− Eq b,
320− Num e,
321− Ord e,
322− KnownNat (I.Count (I.Normalize cols)),
323− KnownNat (I.Count (I.Normalize rows)),
324− I.FromLists e (I.Normalize rows) (I.Normalize cols)
317+ ( Liftable e a b,
318+ CountableDimensionsN cols rows,
319+ FromListsN e rows cols
325320 ) =>
326− (a -> b) ->
327− Matrix e cols rows
321+ (a -> b) -> Matrix e cols rows
328322fromF = M . I.fromF
329323
330324-- | Lifts functions to matrices with dimensions matching @a@ and @b@
331325-- cardinality's.
332326fromF' ::
333− ( Bounded a,
334− Bounded b,
335− Enum a,
336− Enum b,
337− Eq b,
338− Num e,
339− Ord e,
340− KnownNat (I.Count (I.Normalize a)),
341− KnownNat (I.Count (I.Normalize b)),
342− I.FromLists e (I.Normalize b) (I.Normalize a)
327+ ( Liftable e a b,
328+ CountableDimensionsN a b,
329+ FromListsN e b a
343330 ) =>
344− (a -> b) ->
345− Matrix e a b
331+ (a -> b) -> Matrix e a b
346332fromF' = M . I.fromF'
347333
348334-- | Lifts relation functions to Boolean Matrix
349335toRel ::
350− ( Bounded a,
351− Bounded b,
352− Enum a,
353− Enum b,
354− Eq b,
355− KnownNat (I.Count (I.Normalize a)),
356− KnownNat (I.Count (I.Normalize b)),
357− I.FromLists (Natural 0 1) (I.Normalize b) (I.Normalize a)
336+ ( Liftable (Natural 0 1) a b,
337+ CountableDimensionsN a b,
338+ FromListsN (Natural 0 1) b a
358339 ) => (a -> b -> Bool) -> Matrix (Natural 0 1) a b
359340toRel = M . I.toRel
360341
@@ -372,8 +353,8 @@ toList (M m) = I.toList m
372353
373354-- | The zero matrix. A matrix wholly filled with zeros.
374355zeros ::
375− (Num e, I.FromLists e (I.Normalize cols) (I.Normalize rows), KnownNat (I.Count (I.Normalize cols)), KnownNat (I.Count (I.Normalize rows))) =>
376− Matrix e cols rows
356+ (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
357+ => Matrix e cols rows
377358zeros = M I.zeros
378359
379360-- Ones Matrix
@@ -382,8 +363,8 @@ zeros = M I.zeros
382363--
383364-- Also known as T (Top) matrix.
384365ones ::
385− (Num e, I.FromLists e (I.Normalize cols) (I.Normalize rows), KnownNat (I.Count (I.Normalize cols)), KnownNat (I.Count (I.Normalize rows))) =>
386− Matrix e cols rows
366+ (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
367+ => Matrix e cols rows
387368ones = M I.ones
388369
389370-- Const Matrix
@@ -391,9 +372,8 @@ ones = M I.ones
391372-- | The constant matrix constructor. A matrix wholly filled with a given
392373-- value.
393374constant ::
394− (Num e, I.FromLists e (I.Normalize cols) (I.Normalize rows), KnownNat (I.Count (I.Normalize cols)), KnownNat (I.Count (I.Normalize rows))) =>
395− e ->
396− Matrix e cols rows
375+ (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
376+ => e -> Matrix e cols rows
397377constant = M . I.constant
398378
399379-- Bang Matrix
@@ -401,7 +381,7 @@ constant = M . I.constant
401381-- | The T (Top) row vector matrix.
402382bang ::
403383 forall e cols.
404− (Num e, Enum e, I.FromLists e (I.Normalize cols) (), KnownNat (I.Count (I.Normalize cols))) =>
384+ (Num e, Enum e, FromListsN e cols (), CountableN cols) =>
405385 Matrix e cols One
406386bang = M I.bang
407387
@@ -409,7 +389,7 @@ bang = M I.bang
409389
410390-- | Identity matrix
411391identity ::
412− (Num e, I.FromLists e (I.Normalize a) (I.Normalize a), KnownNat (I.Count (I.Normalize a))) =>
392+ (Num e, FromListsN e a a, CountableN a) =>
413393 Matrix e a a
414394identity = M I.identity
415395
@@ -425,11 +405,10 @@ comp (M a) (M b) = M (I.comp a b)
425405-- | Biproduct first component projection
426406p1 ::
427407 ( Num e,
428− KnownNat (I.Count (I.Normalize n)),
429− KnownNat (I.Count (I.Normalize m)),
430− I.FromLists e (I.Normalize n) (I.Normalize m),
431− I.FromLists e (I.Normalize m) (I.Normalize m),
432− I.Normalize (Either m n) ~ Either (I.Normalize m) (I.Normalize n)
408+ CountableDimensionsN n m,
409+ FromListsN e n m,
410+ FromListsN e m m,
411+ TrivialE m n
433412 ) =>
434413 Matrix e (Either m n) m
435414p1 = M I.p1
@@ -437,11 +416,10 @@ p1 = M I.p1
437416-- | Biproduct second component projection
438417p2 ::
439418 ( Num e,
440− KnownNat (I.Count (I.Normalize n)),
441− KnownNat (I.Count (I.Normalize m)),
442− I.FromLists e (I.Normalize m) (I.Normalize n),
443− I.FromLists e (I.Normalize n) (I.Normalize n),
444− I.Normalize (Either m n) ~ Either (I.Normalize m) (I.Normalize n)
419+ CountableDimensionsN n m,
420+ FromListsN e m n,
421+ FromListsN e n n,
422+ TrivialE m n
445423 ) =>
446424 Matrix e (Either m n) n
447425p2 = M I.p2
@@ -451,11 +429,10 @@ p2 = M I.p2
451429-- | Biproduct first component injection
452430i1 ::
453431 ( Num e,
454− KnownNat (I.Count (I.Normalize n)),
455− KnownNat (I.Count (I.Normalize m)),
456− I.FromLists e (I.Normalize n) (I.Normalize m),
457− I.FromLists e (I.Normalize m) (I.Normalize m),
458− I.Normalize (Either m n) ~ Either (I.Normalize m) (I.Normalize n)
432+ CountableDimensionsN n m,
433+ FromListsN e n m,
434+ FromListsN e m m,
435+ TrivialE m n
459436 ) =>
460437 Matrix e m (Either m n)
461438i1 = tr p1
@@ -463,11 +440,10 @@ i1 = tr p1
463440-- | Biproduct second component injection
464441i2 ::
465442 ( Num e,
466− KnownNat (I.Count (I.Normalize n)),
467− KnownNat (I.Count (I.Normalize m)),
468− I.FromLists e (I.Normalize m) (I.Normalize n),
469− I.FromLists e (I.Normalize n) (I.Normalize n),
470− I.Normalize (Either m n) ~ Either (I.Normalize m) (I.Normalize n)
443+ CountableDimensionsN n m,
444+ FromListsN e m n,
445+ FromListsN e n n,
446+ TrivialE m n
471447 ) =>
472448 Matrix e n (Either m n)
473449i2 = tr p2
@@ -481,7 +457,7 @@ i2 = tr p2
481457--
482458-- TODO: A 'rows' function that does not need the 'KnownNat' constraint in
483459-- exchange for performance.
484−rows :: (KnownNat (I.Count (I.Normalize rows))) => Matrix e cols rows -> Int
460+rows :: (CountableN rows) => Matrix e cols rows -> Int
485461rows (M m) = I.rows m
486462
487463-- | Obtain the number of columns.
@@ -491,7 +467,7 @@ rows (M m) = I.rows m
491467--
492468-- TODO: A 'columns' function that does not need the 'KnownNat' constraint in
493469-- exchange for performance.
494−columns :: (KnownNat (I.Count (I.Normalize cols))) => Matrix e cols rows -> Int
470+columns :: (CountableN cols) => Matrix e cols rows -> Int
495471columns (M m) = I.columns m
496472
497473-- Coproduct Bifunctor
@@ -501,14 +477,13 @@ infixl 5 -|-
501477-- | Matrix coproduct functor also known as matrix direct sum.
502478(-|-) ::
503479 ( Num e,
504− KnownNat (I.Count (I.Normalize j)),
505− KnownNat (I.Count (I.Normalize k)),
506− I.FromLists e (I.Normalize k) (I.Normalize k),
507− I.FromLists e (I.Normalize j) (I.Normalize k),
508− I.FromLists e (I.Normalize k) (I.Normalize j),
509− I.FromLists e (I.Normalize j) (I.Normalize j),
510− I.Normalize (Either n m) ~ Either (I.Normalize n) (I.Normalize m),
511− I.Normalize (Either k j) ~ Either (I.Normalize k) (I.Normalize j)
480+ CountableDimensionsN j k,
481+ FromListsN e k k,
482+ FromListsN e j k,
483+ FromListsN e k j,
484+ FromListsN e j j,
485+ TrivialE n m,
486+ TrivialE k j
512487 ) =>
513488 Matrix e n k ->
514489 Matrix e m j ->
@@ -521,11 +496,10 @@ infixl 5 -|-
521496kp1 ::
522497 forall e m k .
523498 ( Num e,
524− KnownNat (I.Count (I.Normalize m)),
525− KnownNat (I.Count (I.Normalize k)),
526− KnownNat (I.Count (I.Normalize (m, k))),
527− I.FromLists e (I.Normalize (m, k)) (I.Normalize m),
528− I.Normalize (m, k) ~ I.Normalize (I.Normalize m, I.Normalize k)
499+ CountableDimensionsN m k,
500+ CountableN (m, k),
501+ FromListsN e (m, k) m,
502+ TrivialP m k
529503 ) => Matrix e (m, k) m
530504kp1 = M (I.kp1 @e @(I.Normalize m) @(I.Normalize k))
531505
@@ -533,11 +507,10 @@ kp1 = M (I.kp1 @e @(I.Normalize m) @(I.Normalize k))
533507kp2 ::
534508 forall e m k.
535509 ( Num e,
536− KnownNat (I.Count (I.Normalize k)),
537− KnownNat (I.Count (I.Normalize m)),
538− KnownNat (I.Count (I.Normalize (m, k))),
539− I.FromLists e (I.Normalize (m, k)) (I.Normalize k),
540− I.Normalize (m, k) ~ I.Normalize (I.Normalize m, I.Normalize k)
510+ CountableDimensionsN k m,
511+ CountableN (m, k),
512+ FromListsN e (m, k) k,
513+ TrivialP m k
541514 ) => Matrix e (m, k) k
542515kp2 = M (I.kp2 @e @(I.Normalize m) @(I.Normalize k))
543516
@@ -555,12 +528,11 @@ kp2 = M (I.kp2 @e @(I.Normalize m) @(I.Normalize k))
555528khatri ::
556529 forall e cols a b.
557530 ( Num e,
558− KnownNat (I.Count (I.Normalize a)),
559− KnownNat (I.Count (I.Normalize b)),
560− KnownNat (I.Count (I.Normalize (a, b))),
561− I.FromLists e (I.Normalize (a, b)) (I.Normalize a),
562− I.FromLists e (I.Normalize (a, b)) (I.Normalize b),
563− I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
531+ CountableDimensionsN a b,
532+ CountableN (a, b),
533+ FromListsN e (a, b) a,
534+ FromListsN e (a, b) b,
535+ TrivialP a b
564536 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (a, b)
565537khatri a b =
566538 let kp1' = kp1 @e @a @b
@@ -575,18 +547,15 @@ infixl 4 ><
575547(><) ::
576548 forall e m p n q.
577549 ( Num e,
578− KnownNat (I.Count (I.Normalize m)),
579− KnownNat (I.Count (I.Normalize n)),
580− KnownNat (I.Count (I.Normalize p)),
581− KnownNat (I.Count (I.Normalize q)),
582− KnownNat (I.Count (I.Normalize (m, n))),
583− KnownNat (I.Count (I.Normalize (p, q))),
584− I.FromLists e (I.Normalize (m, n)) (I.Normalize m),
585− I.FromLists e (I.Normalize (m, n)) (I.Normalize n),
586− I.FromLists e (I.Normalize (p, q)) (I.Normalize p),
587− I.FromLists e (I.Normalize (p, q)) (I.Normalize q),
588− I.Normalize (m, n) ~ I.Normalize (I.Normalize m, I.Normalize n),
589− I.Normalize (p, q) ~ I.Normalize (I.Normalize p, I.Normalize q)
550+ CountableDimensionsN m n,
551+ CountableDimensionsN p q,
552+ CountableDimensionsN (m, n) (p, q),
553+ FromListsN e (m, n) m,
554+ FromListsN e (m, n) n,
555+ FromListsN e (p, q) p,
556+ FromListsN e (p, q) q,
557+ TrivialP m n,
558+ TrivialP p q
590559 ) => Matrix e m p -> Matrix e n q -> Matrix e (m, n) (p, q)
591560(><) a b =
592561 let kp1' = kp1 @e @m @n
@@ -629,9 +598,9 @@ tr (M m) = M (I.tr m)
629598-- ArrowMonad solution presented in the paper.
630599selectM ::
631600 ( Num e,
632− I.FromLists e (I.Normalize b) (I.Normalize b),
633− KnownNat (I.Count (I.Normalize b)),
634− I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)
601+ FromListsN e b b,
602+ CountableN b,
603+ TrivialE a b
635604 ) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
636605selectM (M m) (M y) = M (I.select m y)
637606
@@ -639,15 +608,12 @@ selectM (M m) (M y) = M (I.select m y)
639608
640609-- | McCarthy's Conditional expresses probabilistic choice.
641610cond ::
642− ( I.Normalize (I.Normalize a) ~ I.Normalize a,
643− KnownNat (I.Count (I.Normalize a)),
644− I.FromLists e () (I.Normalize a),
645− I.FromLists e (I.Normalize a) (),
646− I.FromLists e (I.Normalize a) (I.Normalize a),
647− Bounded a,
648− Enum a,
649− Num e,
650− Ord e
611+ ( Trivial a,
612+ CountableN a,
613+ FromListsN e () a,
614+ FromListsN e a (),
615+ FromListsN e a a,
616+ Liftable e a Bool
651617 )
652618 =>
653619 (a -> Bool) -> Matrix e a b -> Matrix e a b -> Matrix e a b
@@ -656,9 +622,9 @@ cond p (M a) (M b) = M (I.cond p a b)
656622-- Pretty print
657623
658624-- | Matrix pretty printer
659−pretty :: (KnownNat (I.Count (I.Normalize cols)), Show e) => Matrix e cols rows -> String
625+pretty :: (CountableN cols, Show e) => Matrix e cols rows -> String
660626pretty (M m) = I.pretty m
661627
662628-- | Matrix pretty printer
663−prettyPrint :: (KnownNat (I.Count (I.Normalize cols)), Show e) => Matrix e cols rows -> IO ()
629+prettyPrint :: (CountableN cols, Show e) => Matrix e cols rows -> IO ()
664630prettyPrint (M m) = I.prettyPrint m