cybus 0.2.0.0 → 0.3.0.0
raw patch · 10 files changed
+660/−395 lines, 10 filesdep −pretty-simpledep ~posdep ~primusPVP ok
version bump matches the API change (PVP)
Dependencies removed: pretty-simple
Dependency ranges changed: pos, primus
API changes (from Hackage documentation)
- Cybus.Fin: instance Data.Pos.PosT n => GHC.Base.Monoid (Cybus.Fin.Fin n)
- Cybus.Fin: instance Data.Pos.PosT n => GHC.Enum.Bounded (Cybus.Fin.Fin n)
- Cybus.Fin: instance Data.Pos.PosT n => GHC.Enum.Enum (Cybus.Fin.Fin n)
- Cybus.Fin: instance Data.Pos.PosT n => GHC.Num.Num (Cybus.Fin.Fin n)
- Cybus.Fin: instance Data.Pos.PosT n => GHC.Read.Read (Cybus.Fin.Fin n)
- Cybus.Fin: instance Data.Pos.PosT n => Primus.Num1.Num1 (Cybus.Fin.Fin n)
- Cybus.Fin: type FinT i n = (i <=! n, PosT n)
- Cybus.Fin: type FinWithMessageT msg i n = (LTEQT msg i n, PosT n)
- Cybus.Mat: instance (Cybus.Fin.FinT i n, Cybus.Mat.SliceC (i1 : is) (n1 : ns)) => Cybus.Mat.SliceC (i : i1 : is) (n : n1 : ns)
- Cybus.Mat: instance (Data.Pos.PosT n, Cybus.Mat.MatConvertersC (m : ns)) => Cybus.Mat.MatConvertersC (n : m : ns)
- Cybus.Mat: instance Cybus.Fin.FinT 1 n => Cybus.Mat.Row1 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 1 n => Cybus.Mat.Row1 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 10 n => Cybus.Mat.Row10 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 10 n => Cybus.Mat.Row10 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 2 n => Cybus.Mat.Row2 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 2 n => Cybus.Mat.Row2 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 3 n => Cybus.Mat.Row3 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 3 n => Cybus.Mat.Row3 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 4 n => Cybus.Mat.Row4 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 4 n => Cybus.Mat.Row4 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 5 n => Cybus.Mat.Row5 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 5 n => Cybus.Mat.Row5 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 6 n => Cybus.Mat.Row6 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 6 n => Cybus.Mat.Row6 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 7 n => Cybus.Mat.Row7 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 7 n => Cybus.Mat.Row7 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 8 n => Cybus.Mat.Row8 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 8 n => Cybus.Mat.Row8 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT 9 n => Cybus.Mat.Row9 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
- Cybus.Mat: instance Cybus.Fin.FinT 9 n => Cybus.Mat.Row9 (Cybus.Mat.Vec n a) a
- Cybus.Mat: instance Cybus.Fin.FinT i n => Cybus.Mat.SliceC '[i] '[n]
- Cybus.Mat: instance Cybus.Fin.FinT i n => Cybus.Mat.SliceC '[i] (n : m : ns)
- Cybus.Mat: instance Data.Pos.PosT n => Cybus.Mat.MatConvertersC '[n]
- Cybus.NatHelper: instance (Data.Pos.PosT n, Cybus.NatHelper.NestedListC (n1 : ns)) => Cybus.NatHelper.NestedListC (n : n1 : ns)
- Cybus.NatHelper: instance Data.Pos.PosT n => Cybus.NatHelper.NestedListC '[n]
+ Cybus.Fin: class (PosC i, PosC n) => FinC i n
+ Cybus.Fin: class FinWithMessageC msg i n
+ Cybus.Fin: instance (Data.Pos.PosC n, i Cybus.NatHelper.<=! n) => Cybus.Fin.FinC i n
+ Cybus.Fin: instance Cybus.NatHelper.LTEQT msg i n => Cybus.Fin.FinWithMessageC msg i n
+ Cybus.Fin: instance Data.Pos.PosC n => GHC.Base.Monoid (Cybus.Fin.Fin n)
+ Cybus.Fin: instance Data.Pos.PosC n => GHC.Enum.Bounded (Cybus.Fin.Fin n)
+ Cybus.Fin: instance Data.Pos.PosC n => GHC.Enum.Enum (Cybus.Fin.Fin n)
+ Cybus.Fin: instance Data.Pos.PosC n => GHC.Num.Num (Cybus.Fin.Fin n)
+ Cybus.Fin: instance Data.Pos.PosC n => GHC.Read.Read (Cybus.Fin.Fin n)
+ Cybus.Fin: instance Data.Pos.PosC n => Primus.Num1.Num1 (Cybus.Fin.Fin n)
+ Cybus.FinMat: _finMatCons :: forall n n1 ns. (NS (n1 : ns), PosC n) => Iso' (FinMat (n : (n1 : ns))) (Fin n, FinMat (n1 : ns))
+ Cybus.Mat: deleteColumnL :: forall a. Pos -> Int -> [a] -> [a]
+ Cybus.Mat: determinant :: Num a => Mat2 n n a -> a
+ Cybus.Mat: instance (Cybus.Fin.FinC i n, Cybus.Mat.SliceC (i1 : is) (n1 : ns)) => Cybus.Mat.SliceC (i : i1 : is) (n : n1 : ns)
+ Cybus.Mat: instance (Data.Pos.PosC n, Cybus.Mat.MatConvertersC (m : ns)) => Cybus.Mat.MatConvertersC (n : m : ns)
+ Cybus.Mat: instance Cybus.Fin.FinC 1 n => Cybus.Mat.Row1 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 1 n => Cybus.Mat.Row1 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 10 n => Cybus.Mat.Row10 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 10 n => Cybus.Mat.Row10 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 2 n => Cybus.Mat.Row2 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 2 n => Cybus.Mat.Row2 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 3 n => Cybus.Mat.Row3 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 3 n => Cybus.Mat.Row3 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 4 n => Cybus.Mat.Row4 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 4 n => Cybus.Mat.Row4 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 5 n => Cybus.Mat.Row5 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 5 n => Cybus.Mat.Row5 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 6 n => Cybus.Mat.Row6 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 6 n => Cybus.Mat.Row6 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 7 n => Cybus.Mat.Row7 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 7 n => Cybus.Mat.Row7 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 8 n => Cybus.Mat.Row8 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 8 n => Cybus.Mat.Row8 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC 9 n => Cybus.Mat.Row9 (Cybus.Mat.Mat (n : m : ns) a) (Cybus.Mat.Mat (m : ns) a)
+ Cybus.Mat: instance Cybus.Fin.FinC 9 n => Cybus.Mat.Row9 (Cybus.Mat.Vec n a) a
+ Cybus.Mat: instance Cybus.Fin.FinC i n => Cybus.Mat.SliceC '[i] '[n]
+ Cybus.Mat: instance Cybus.Fin.FinC i n => Cybus.Mat.SliceC '[i] (n : m : ns)
+ Cybus.Mat: instance Data.Pos.PosC n => Cybus.Mat.MatConvertersC '[n]
+ Cybus.Mat: rotateLeft :: Mat2 n m a -> Mat2 m n a
+ Cybus.Mat: rotateRight :: Mat2 n m a -> Mat2 m n a
+ Cybus.NatHelper: instance (Data.Pos.PosC n, Cybus.NatHelper.NestedListC (n1 : ns)) => Cybus.NatHelper.NestedListC (n : n1 : ns)
+ Cybus.NatHelper: instance (GHC.TypeNats.KnownNat i, GHC.TypeNats.KnownNat n, Primus.TypeLevel.FailUnless (i GHC.TypeNats.<=? n) ((('GHC.TypeLits.Text "LTEQC n: requires n >= i but found i=" 'GHC.TypeLits.:<>: 'GHC.TypeLits.ShowType i) 'GHC.TypeLits.:<>: 'GHC.TypeLits.Text " n=") 'GHC.TypeLits.:<>: 'GHC.TypeLits.ShowType n)) => Cybus.NatHelper.LTEQC i n
+ Cybus.NatHelper: instance Data.Pos.PosC n => Cybus.NatHelper.NestedListC '[n]
- Cybus.Fin: _F1 :: FinT 1 n => Fin n
+ Cybus.Fin: _F1 :: FinC 1 n => Fin n
- Cybus.Fin: _F10 :: FinT 10 n => Fin n
+ Cybus.Fin: _F10 :: FinC 10 n => Fin n
- Cybus.Fin: _F11 :: FinT 11 n => Fin n
+ Cybus.Fin: _F11 :: FinC 11 n => Fin n
- Cybus.Fin: _F12 :: FinT 12 n => Fin n
+ Cybus.Fin: _F12 :: FinC 12 n => Fin n
- Cybus.Fin: _F13 :: FinT 13 n => Fin n
+ Cybus.Fin: _F13 :: FinC 13 n => Fin n
- Cybus.Fin: _F14 :: FinT 14 n => Fin n
+ Cybus.Fin: _F14 :: FinC 14 n => Fin n
- Cybus.Fin: _F15 :: FinT 15 n => Fin n
+ Cybus.Fin: _F15 :: FinC 15 n => Fin n
- Cybus.Fin: _F16 :: FinT 16 n => Fin n
+ Cybus.Fin: _F16 :: FinC 16 n => Fin n
- Cybus.Fin: _F17 :: FinT 17 n => Fin n
+ Cybus.Fin: _F17 :: FinC 17 n => Fin n
- Cybus.Fin: _F18 :: FinT 18 n => Fin n
+ Cybus.Fin: _F18 :: FinC 18 n => Fin n
- Cybus.Fin: _F19 :: FinT 19 n => Fin n
+ Cybus.Fin: _F19 :: FinC 19 n => Fin n
- Cybus.Fin: _F2 :: FinT 2 n => Fin n
+ Cybus.Fin: _F2 :: FinC 2 n => Fin n
- Cybus.Fin: _F20 :: FinT 20 n => Fin n
+ Cybus.Fin: _F20 :: FinC 20 n => Fin n
- Cybus.Fin: _F3 :: FinT 3 n => Fin n
+ Cybus.Fin: _F3 :: FinC 3 n => Fin n
- Cybus.Fin: _F4 :: FinT 4 n => Fin n
+ Cybus.Fin: _F4 :: FinC 4 n => Fin n
- Cybus.Fin: _F5 :: FinT 5 n => Fin n
+ Cybus.Fin: _F5 :: FinC 5 n => Fin n
- Cybus.Fin: _F6 :: FinT 6 n => Fin n
+ Cybus.Fin: _F6 :: FinC 6 n => Fin n
- Cybus.Fin: _F7 :: FinT 7 n => Fin n
+ Cybus.Fin: _F7 :: FinC 7 n => Fin n
- Cybus.Fin: _F8 :: FinT 8 n => Fin n
+ Cybus.Fin: _F8 :: FinC 8 n => Fin n
- Cybus.Fin: _F9 :: FinT 9 n => Fin n
+ Cybus.Fin: _F9 :: FinC 9 n => Fin n
- Cybus.Fin: fin :: PosT n => Int -> Either String (Fin n)
+ Cybus.Fin: fin :: PosC n => Int -> Either String (Fin n)
- Cybus.Fin: finC :: forall (i :: Nat) (n :: Nat). FinT i n => Fin n
+ Cybus.Fin: finC :: FinC i n => Fin n
- Cybus.Fin: finP :: forall n. PosT n => Pos -> Either String (Fin n)
+ Cybus.Fin: finP :: forall n. PosC n => Pos -> Either String (Fin n)
- Cybus.Fin: mkFinC :: forall n. PosT n => Pos -> Pos -> Either String (Fin n)
+ Cybus.Fin: mkFinC :: forall n. PosC n => Pos -> Pos -> Either String (Fin n)
- Cybus.Fin: pattern FinU :: forall (n :: Nat). (HasCallStack, PosT n) => Pos -> Pos -> Fin n
+ Cybus.Fin: pattern FinU :: forall (n :: Nat). (HasCallStack, PosC n) => Pos -> Pos -> Fin n
- Cybus.Fin: readFin :: PosT n => ReadS (Fin n)
+ Cybus.Fin: readFin :: PosC n => ReadS (Fin n)
- Cybus.Fin: readFinP :: forall n. PosT n => ReadP (Fin n)
+ Cybus.Fin: readFinP :: forall n. PosC n => ReadP (Fin n)
- Cybus.FinMat: _finMatFin :: forall i n ns. (PosT i, NSRangeC (NatToPeanoT i) ns) => Lens' (FinMat ns) (Fin n)
+ Cybus.FinMat: _finMatFin :: forall i n ns. (PosC i, NSRangeC (NatToPeanoT i) ns) => Lens' (FinMat ns) (Fin n)
- Cybus.FinMat: finMatFinGet :: forall i n ns. (PosT i, NSRangeC (NatToPeanoT i) ns) => FinMat ns -> Fin n
+ Cybus.FinMat: finMatFinGet :: forall i n ns. (PosC i, NSRangeC (NatToPeanoT i) ns) => FinMat ns -> Fin n
- Cybus.FinMat: finMatFinSet :: forall i n ns. (PosT i, NSRangeC (NatToPeanoT i) ns) => FinMat ns -> Fin n -> FinMat ns
+ Cybus.FinMat: finMatFinSet :: forall i n ns. (PosC i, NSRangeC (NatToPeanoT i) ns) => FinMat ns -> Fin n -> FinMat ns
- Cybus.Mat: _c1 :: FinT 1 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c1 :: FinC 1 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c10 :: FinT 10 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c10 :: FinC 10 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c2 :: FinT 2 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c2 :: FinC 2 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c3 :: FinT 3 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c3 :: FinC 3 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c4 :: FinT 4 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c4 :: FinC 4 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c5 :: FinT 5 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c5 :: FinC 5 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c6 :: FinT 6 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c6 :: FinC 6 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c7 :: FinT 7 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c7 :: FinC 7 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c8 :: FinT 8 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c8 :: FinC 8 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _c9 :: FinT 9 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _c9 :: FinC 9 m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: _col :: forall (i :: Nat) n m ns a. FinT i m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
+ Cybus.Mat: _col :: forall (i :: Nat) n m ns a. FinC i m => Lens' (Mat (n : (m : ns)) a) (Mat (n : ns) a)
- Cybus.Mat: deleteCol :: forall (i :: Nat) (n :: Nat) (n1 :: Nat) ns a. FinT i (1 + n1) => Mat (n : ((1 + n1) : ns)) a -> Mat (n : (n1 : ns)) a
+ Cybus.Mat: deleteCol :: forall (i :: Nat) (n :: Nat) (n1 :: Nat) ns a. FinC i (1 + n1) => Mat (n : ((1 + n1) : ns)) a -> Mat (n : (n1 : ns)) a
- Cybus.Mat: deleteRow :: forall (i :: Nat) (n :: Nat) (ns :: [Nat]) a. FinT i (1 + n) => Mat ((1 + n) : ns) a -> Mat (n : ns) a
+ Cybus.Mat: deleteRow :: forall (i :: Nat) (n :: Nat) (ns :: [Nat]) a. FinC i (1 + n) => Mat ((1 + n) : ns) a -> Mat (n : ns) a
- Cybus.Mat: insertCol :: forall (i :: Nat) (n :: Nat) (n1 :: Nat) ns a. FinT i (1 + n1) => Mat (n : ns) a -> Mat (n : (n1 : ns)) a -> Mat (n : ((1 + n1) : ns)) a
+ Cybus.Mat: insertCol :: forall (i :: Nat) (n :: Nat) (n1 :: Nat) ns a. FinC i (1 + n1) => Mat (n : ns) a -> Mat (n : (n1 : ns)) a -> Mat (n : ((1 + n1) : ns)) a
- Cybus.Mat: insertRow :: forall i n m ns a. FinT i (1 + n) => Mat (m : ns) a -> Mat (n : (m : ns)) a -> Mat ((1 + n) : (m : ns)) a
+ Cybus.Mat: insertRow :: forall i n m ns a. FinC i (1 + n) => Mat (m : ns) a -> Mat (n : (m : ns)) a -> Mat ((1 + n) : (m : ns)) a
- Cybus.Mat: mat2 :: forall n m a. (HasCallStack, PosT n, PosT m) => [a] -> Mat2 n m a
+ Cybus.Mat: mat2 :: forall n m a. (HasCallStack, PosC n, PosC m) => [a] -> Mat2 n m a
- Cybus.Mat: mat2' :: forall n m a. (HasCallStack, PosT n, PosT m) => [a] -> Mat2 n m a
+ Cybus.Mat: mat2' :: forall n m a. (HasCallStack, PosC n, PosC m) => [a] -> Mat2 n m a
- Cybus.Mat: nestedListToMatValidated :: forall ns x a. (x ~ ListNST ns a, ValidateNestedListC x (ValidateNestedListT x), MatConvertersC ns) => ListNST ns a -> Either String (Mat ns a)
+ Cybus.Mat: nestedListToMatValidated :: forall ns a x. (x ~ ListNST ns a, ValidateNestedListC x (ValidateNestedListT x), MatConvertersC ns) => ListNST ns a -> Either String (Mat ns a)
- Cybus.Mat: nestedNonEmptyToMatValidated :: forall ns x a. (x ~ NonEmptyNST ns a, ValidateNestedNonEmptyC x (ValidateNestedNonEmptyT x), MatConvertersC ns) => NonEmptyNST ns a -> Either String (Mat ns a)
+ Cybus.Mat: nestedNonEmptyToMatValidated :: forall ns a x. (x ~ NonEmptyNST ns a, ValidateNestedNonEmptyC x (ValidateNestedNonEmptyT x), MatConvertersC ns) => NonEmptyNST ns a -> Either String (Mat ns a)
- Cybus.Mat: nonEmptyMatsToMat :: forall n m ns a t. (Foldable1 t, PosT n) => t (Mat (m : ns) a) -> Either String (Mat (n : (m : ns)) a)
+ Cybus.Mat: nonEmptyMatsToMat :: forall n m ns a t. (Foldable1 t, PosC n) => t (Mat (m : ns) a) -> Either String (Mat (n : (m : ns)) a)
- Cybus.Mat: readMat2 :: (MatConvertersC '[n, m], PosT n, PosT m, Read [[a]]) => ReadS (Mat2 n m a)
+ Cybus.Mat: readMat2 :: (MatConvertersC '[n, m], PosC n, PosC m, Read [[a]]) => ReadS (Mat2 n m a)
- Cybus.Mat: readVec :: (MatConvertersC '[n], PosT n, Read [a]) => ReadS (Vec n a)
+ Cybus.Mat: readVec :: (MatConvertersC '[n], PosC n, Read [a]) => ReadS (Vec n a)
- Cybus.Mat: replicateMat :: forall n n1 ns a. PosT n => Mat (n1 : ns) a -> Mat (n : (n1 : ns)) a
+ Cybus.Mat: replicateMat :: forall n n1 ns a. PosC n => Mat (n1 : ns) a -> Mat (n : (n1 : ns)) a
- Cybus.Mat: swapCol :: forall (i :: Nat) (j :: Nat) (n :: Nat) (n1 :: Nat) ns a. (FinT i n1, FinT j n1) => Mat (n : (n1 : ns)) a -> Mat (n : (n1 : ns)) a
+ Cybus.Mat: swapCol :: forall (i :: Nat) (j :: Nat) (n :: Nat) (n1 :: Nat) ns a. (FinC i n1, FinC j n1) => Mat (n : (n1 : ns)) a -> Mat (n : (n1 : ns)) a
- Cybus.Mat: swapRow :: forall (i :: Nat) (j :: Nat) (n :: Nat) ns a. (FinT i n, FinT j n) => Mat (n : ns) a -> Mat (n : ns) a
+ Cybus.Mat: swapRow :: forall (i :: Nat) (j :: Nat) (n :: Nat) ns a. (FinC i n, FinC j n) => Mat (n : ns) a -> Mat (n : ns) a
- Cybus.Mat: toND :: forall i ns a. i <=! i => Mat ns a -> MatToNDT i ns a
+ Cybus.Mat: toND :: forall i ns a. PosC i => Mat ns a -> MatToNDT i ns a
- Cybus.Mat: vec :: forall n a. (HasCallStack, PosT n) => [a] -> Vec n a
+ Cybus.Mat: vec :: forall n a. (HasCallStack, PosC n) => [a] -> Vec n a
- Cybus.Mat: vec' :: forall n a. (HasCallStack, PosT n) => [a] -> Vec n a
+ Cybus.Mat: vec' :: forall n a. (HasCallStack, PosC n) => [a] -> Vec n a
- Cybus.NatHelper: type LTEQT msg i n = (FailUnless (i <=? n) ('Text "i>n" :<>: 'Text ": i=" :<>: 'ShowType i :<>: 'Text " n=" :<>: 'ShowType n :<>: msg), PosT i)
+ Cybus.NatHelper: type LTEQT msg i n = (FailUnless (i <=? n) ('Text "i>n" :<>: 'Text ": i=" :<>: 'ShowType i :<>: 'Text " n=" :<>: 'ShowType n :<>: msg), PosC i)
Files
- app/Main.hs +29/−6
- cybus.cabal +7/−8
- src/Cybus/Fin.hs +49/−48
- src/Cybus/FinMat.hs +29/−18
- src/Cybus/Mat.hs +265/−203
- src/Cybus/NatHelper.hs +32/−16
- test/TestFin.hs +4/−4
- test/TestFinMat.hs +37/−27
- test/TestMat.hs +207/−64
- test/TestNatHelper.hs +1/−1
app/Main.hs view
@@ -1,14 +1,17 @@+{-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeApplications #-} module Main where --import Data.List.NonEmpty (NonEmpty(..)) --import qualified Data.List.NonEmpty as N+import qualified GHC.TypeNats as GN import Cybus main :: IO ()-main = putStr $ show $ mm @(NN 234)+main = putStr $ show $ mm @'[2,3,4] tst1 :: Mat '[4,5,3] Int tst1 = gen id@@ -21,22 +24,42 @@ tst4 :: Mat2 4 7 Int tst4 = mat2 @4 @3 [1..] `multMat` mat2 @3 @7 [1..]++tst5 :: Mat (2 ': ns) a -> Mat (1 ': ns) a+tst5 = deleteRow @2++tst6 :: FinC 1 (1 GN.+ n) => Mat (1 GN.+ n ': ns) a -> Mat (n ': ns) a+tst6 = deleteRow @1+ {-->tst3 (mm @234)-Mat@[2]-[Mat@[3,4]+>tst3 (mm @'[2,3,4])+Vec@2 [Mat2@(3,4) [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ]-,Mat@[3,4]+,Mat2@(3,4) [ [13,14,15,16], [17,18,19,20], [21,22,23,24] ] ]+it :: Mat '[2] (Mat '[3, 4] Int) -it :: Mat '[2] (Mat '[3,4] Int)+>tst6 (mm @'[9,3])+Mat2@(8,3)+ [+ [4,5,6],+ [7,8,9],+ [10,11,12],+ [13,14,15],+ [16,17,18],+ [19,20,21],+ [22,23,24],+ [25,26,27]+ ]++it :: Mat '[8, 3] Int -}
cybus.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: cybus-version: 0.2.0.0+version: 0.3.0.0 synopsis: multi-dimensional arrays description: A library for typesafe multi-dimensional arrays . Please see the README on GitHub at <https://github.com/gbwey/cybus#readme> category: Data, Containers@@ -41,8 +41,8 @@ , distributive , indexed-traversable , mtl- , pos >=0.2.0.0- , primus >=0.2.0.0+ , pos >=0.3.0.0+ , primus >=0.3.0.0 , profunctors , semigroupoids , these@@ -65,8 +65,8 @@ , distributive , indexed-traversable , mtl- , pos >=0.2.0.0- , primus >=0.2.0.0+ , pos >=0.3.0.0+ , primus >=0.3.0.0 , profunctors , semigroupoids , these@@ -99,9 +99,8 @@ , indexed-traversable , lens , mtl- , pos >=0.2.0.0- , pretty-simple- , primus >=0.2.0.0+ , pos >=0.3.0.0+ , primus >=0.3.0.0 , profunctors , semigroupoids , tasty
src/Cybus/Fin.hs view
@@ -32,9 +32,8 @@ fnN, pattern Fin, pattern FinU,- FinT,- FinWithMessageT,- finC,+ FinC (..),+ FinWithMessageC, -- * read/show methods showFin,@@ -113,17 +112,17 @@ {-# COMPLETE FinU #-} --- | pattern synonym for validating the fin before construction with a PosT constraint for validating at the typelevel+-- | pattern synonym for validating the fin before construction with a PosC constraint for validating at the typelevel pattern FinU :: forall (n :: Nat).- (HasCallStack, PosT n) =>+ (HasCallStack, PosC n) => Pos -> Pos -> Fin n pattern FinU i n <- Fin' i n where- FinU = frp .@ mkFinC -- dont change this: frp is good else breaking the system+ FinU = frp .@ mkFinC -- | create a 'Fin' value level "i" and "n" values and validate that "i" is in range mkFin :: Pos -> Pos -> Either String (Fin n)@@ -133,7 +132,7 @@ else Left $ show p ++ " is too large: maximum is " ++ show n -- | create a 'Fin' value level "i" and "n" values and validate against expected "n"-mkFinC :: forall n. PosT n => Pos -> Pos -> Either String (Fin n)+mkFinC :: forall n. PosC n => Pos -> Pos -> Either String (Fin n) mkFinC p n = do let n' = fromNP @n if n == n'@@ -141,21 +140,21 @@ else Left $ "mkFinC: " ++ show n ++ " /= " ++ show n' ++ " at typelevel" -- | convenience function for conversion from 'Int' to 'Fin'-fin :: PosT n => Int -> Either String (Fin n)+fin :: PosC n => Int -> Either String (Fin n) fin = finP <=< eitherPos -- | convenience function for conversion from 'Pos' to 'Fin'-finP :: forall n. PosT n => Pos -> Either String (Fin n)+finP :: forall n. PosC n => Pos -> Either String (Fin n) finP = flip mkFinC (fromNP @n) -instance PosT n => Monoid (Fin n) where+instance PosC n => Monoid (Fin n) where mempty = minBound instance Semigroup (Fin n) where (<>) = max --- PosT only needed for fromInteger-instance PosT n => Num (Fin n) where+-- PosC only needed for fromInteger+instance PosC n => Num (Fin n) where (+) = forceRight "(+)" .@ withOp2 (+) (-) = forceRight "(-)" .@ withOp2 (-) (*) = forceRight "(*)" .@ withOp2 (*)@@ -167,18 +166,18 @@ k <- eitherPos ii mkFinC k (fromNP @n) -instance PosT n => Num1 (Fin n) where+instance PosC n => Num1 (Fin n) where signum1 = fmap signum -- have to override as 1 is Fin 2 (there is no zero) -instance PosT n => Enum (Fin n) where+instance PosC n => Enum (Fin n) where toEnum i = forceRight "Enum(Fin n):toEnum" $ do p <- eitherPos (i + 1) mkFinC p (fromNP @n)- fromEnum = subtract 1 . unP . fnPos -- todo: ok subtract one could be a problem+ fromEnum = subtract 1 . unP . fnPos enumFrom = boundedEnumFrom enumFromThen = boundedEnumFromThen -instance PosT n => Bounded (Fin n) where+instance PosC n => Bounded (Fin n) where minBound = FinU _1P (fromNP @n) maxBound = FinU (fromNP @n) (fromNP @n) @@ -186,15 +185,15 @@ showFin :: Fin n -> String showFin (Fin (Pos i) (Pos n)) = "Fin" ++ show (i, n) -instance PosT n => Read (Fin n) where+instance PosC n => Read (Fin n) where readPrec = PC.readP_to_Prec (const readFinP) -- | reader for 'Fin'-readFin :: PosT n => ReadS (Fin n)+readFin :: PosC n => ReadS (Fin n) readFin = P.readP_to_S readFinP -- | reader for 'showFin'-readFinP :: forall n. PosT n => P.ReadP (Fin n)+readFinP :: forall n. PosC n => P.ReadP (Fin n) readFinP = do P.skipSpaces (i, n) <- P.between (P.string "Fin(") (P.string ")") ((,) <$> pPosInt <* P.char ',' <*> pPosInt)@@ -203,94 +202,96 @@ instance Show (Fin n) where show = showFin --- | create a 'Fin' using typelevel "i" and "n" Nat-finC :: forall (i :: Nat) (n :: Nat). FinT i n => Fin n-finC = Fin' (fromNP @i) (fromNP @n)+-- | class for constraining "i" to positive numbers less than or equal to "n"+type FinC :: Nat -> Nat -> Constraint+class (PosC i, PosC n) => FinC i n where+ finC :: Fin n --- | type constraint for restricting a 'Nat' to positive numbers-type FinT :: Nat -> Nat -> Constraint-type FinT i n = (i <=! n, PosT n)+instance (PosC n, i <=! n) => FinC i n where+ finC = Fin' (fromNP @i) (fromNP @n) --- | type constraint for restricting a 'Nat' to positive numbers with a custom error message-type FinWithMessageT :: GL.ErrorMessage -> Nat -> Nat -> Constraint-type FinWithMessageT msg i n = (LTEQT msg i n, PosT n)+-- | class for constraining "i" to positive numbers less than or equal to "n" with a custom error message+type FinWithMessageC :: GL.ErrorMessage -> Nat -> Nat -> Constraint+class FinWithMessageC msg i n +instance LTEQT msg i n => FinWithMessageC msg i n+ -- | type synonym for index 1-_F1 :: FinT 1 n => Fin n+_F1 :: FinC 1 n => Fin n _F1 = finC @1 -- | type synonym for index 2-_F2 :: FinT 2 n => Fin n+_F2 :: FinC 2 n => Fin n _F2 = finC @2 -- | type synonym for index 3-_F3 :: FinT 3 n => Fin n+_F3 :: FinC 3 n => Fin n _F3 = finC @3 -- | type synonym for index 4-_F4 :: FinT 4 n => Fin n+_F4 :: FinC 4 n => Fin n _F4 = finC @4 -- | type synonym for index 5-_F5 :: FinT 5 n => Fin n+_F5 :: FinC 5 n => Fin n _F5 = finC @5 -- | type synonym for index 6-_F6 :: FinT 6 n => Fin n+_F6 :: FinC 6 n => Fin n _F6 = finC @6 -- | type synonym for index 7-_F7 :: FinT 7 n => Fin n+_F7 :: FinC 7 n => Fin n _F7 = finC @7 -- | type synonym for index 8-_F8 :: FinT 8 n => Fin n+_F8 :: FinC 8 n => Fin n _F8 = finC @8 -- | type synonym for index 9-_F9 :: FinT 9 n => Fin n+_F9 :: FinC 9 n => Fin n _F9 = finC @9 -- | type synonym for index 10-_F10 :: FinT 10 n => Fin n+_F10 :: FinC 10 n => Fin n _F10 = finC @10 -- | type synonym for index 11-_F11 :: FinT 11 n => Fin n+_F11 :: FinC 11 n => Fin n _F11 = finC @11 -- | type synonym for index 12-_F12 :: FinT 12 n => Fin n+_F12 :: FinC 12 n => Fin n _F12 = finC @12 -- | type synonym for index 13-_F13 :: FinT 13 n => Fin n+_F13 :: FinC 13 n => Fin n _F13 = finC @13 -- | type synonym for index 14-_F14 :: FinT 14 n => Fin n+_F14 :: FinC 14 n => Fin n _F14 = finC @14 -- | type synonym for index 15-_F15 :: FinT 15 n => Fin n+_F15 :: FinC 15 n => Fin n _F15 = finC @15 -- | type synonym for index 16-_F16 :: FinT 16 n => Fin n+_F16 :: FinC 16 n => Fin n _F16 = finC @16 -- | type synonym for index 17-_F17 :: FinT 17 n => Fin n+_F17 :: FinC 17 n => Fin n _F17 = finC @17 -- | type synonym for index 18-_F18 :: FinT 18 n => Fin n+_F18 :: FinC 18 n => Fin n _F18 = finC @18 -- | type synonym for index 19-_F19 :: FinT 19 n => Fin n+_F19 :: FinC 19 n => Fin n _F19 = finC @19 -- | type synonym for index 20-_F20 :: FinT 20 n => Fin n+_F20 :: FinC 20 n => Fin n _F20 = finC @20
src/Cybus/FinMat.hs view
@@ -59,6 +59,7 @@ finMatFinGet, -- * lens into the matrix indices+ _finMatCons, _finMatFin, _i1, _i2,@@ -134,7 +135,7 @@ pattern FinMatU i ps <- FinMatUnsafe i ps where- FinMatU = frp .@ mkFinMatC -- dont change this: frp is necessary else breaking the system+ FinMatU = frp .@ mkFinMatC -- | create a FinMat value level "i" and "ns" values and validate that "i" is in range mkFinMat :: Int -> NonEmpty Pos -> Either String (FinMat ns)@@ -184,9 +185,9 @@ FinMatT _is0 _ns0 ind '[] '[] = GL.TypeError ( 'GL.Text "FinMatT: empty index 'is' and 'ns' " 'GL.:<>: 'GL.ShowType ind) FinMatT _is0 _ns0 ind '[i] '[n] =- FinWithMessageT ( 'GL.Text " at index " 'GL.:<>: 'GL.ShowType ind) i n+ FinWithMessageC ( 'GL.Text " at index " 'GL.:<>: 'GL.ShowType ind) i n FinMatT is0 ns0 ind (i ': i' ': is) (n ': n' ': ns) =- (FinWithMessageT ( 'GL.Text " at index=" 'GL.:<>: 'GL.ShowType ind) i n, FinMatT is0 ns0 (ind GN.+ 1) (i' ': is) (n' ': ns))+ (FinWithMessageC ( 'GL.Text " at index=" 'GL.:<>: 'GL.ShowType ind) i n, FinMatT is0 ns0 (ind GN.+ 1) (i' ': is) (n' ': ns)) FinMatT is0 ns0 _ind (_ ': _ ': _) '[_] = GL.TypeError ( 'GL.Text "too many indices: length is > length ns:"@@ -284,7 +285,8 @@ readFinMatP :: forall ns. NS ns => P.ReadP (FinMat ns) readFinMatP = do P.skipSpaces- (i, ns) <- (,) <$> pInt <* P.char '@' <*> pPositives '{' '}'+ _ <- P.string "FinMat@"+ (i, ns) <- (,) <$> pInt <*> pPositives '{' '}' either (const P.pfail) pure $ mkFinMatC @ns i ns neToString :: NonEmpty Pos -> String@@ -293,12 +295,12 @@ -- | pretty print FinMat showFinMat :: FinMat ns -> String showFinMat (FinMat i ns) =- show i ++ "@{" ++ neToString ns ++ "}"+ "FinMat@" ++ show i ++ "{" ++ neToString ns ++ "}" -- | more detailed pretty print FinMat showFinMat' :: forall ns. FinMat ns -> String showFinMat' w@(FinMat i ns) =- show i ++ "@{" ++ neToString (finMatToNonEmpty w) ++ "|" ++ neToString ns ++ "}"+ "FinMat@" ++ show i ++ "{" ++ neToString (finMatToNonEmpty w) ++ "|" ++ neToString ns ++ "}" instance Show (FinMat ns) where show = showFinMat@@ -307,7 +309,7 @@ type NSRangeC :: Peano -> [Nat] -> Constraint class NSRangeC i ns -instance GL.TypeError ('GL.Text "NSRangeC '[]: empty indices") => NSRangeC p '[]+instance GL.TypeError ( 'GL.Text "NSRangeC '[]: empty indices") => NSRangeC p '[] instance NSRangeC ( 'S 'Z) (n ': ns) instance NSRangeC ( 'S i) (m ': ns) => NSRangeC ( 'S ( 'S i)) (n ': m ': ns) instance@@ -318,42 +320,50 @@ GL.TypeError ( 'GL.Text "NSRangeC: zero is not a valid index: index must be one or greater") => NSRangeC 'Z (n ': ns) +-- | iso that conses out the 'Fin' from 'FinMat'+_finMatCons :: forall n n1 ns . (NS (n1 ': ns), PosC n) => Iso' (FinMat (n ': n1 ': ns)) (Fin n, FinMat (n1 ': ns))+_finMatCons = iso f g+ where f (FinMat is (_:|ns)) = forceRightP "_finMatCons lhs" $ do+ let (a,Pos b) = divModNextP is (productP ns)+ (,) <$> fin @n (a+1) <*> finMat @(n1 ': ns) (b-1)+ g (Fin (Pos i) _, FinMat is ns) = forceRightP "_finMatCons rhs" $ finMat @(n ': n1 ': ns) (is + (i-1) * productPInt ns)+ -- | a lens for accessing the "i" index in a indices of FinMat _finMatFin :: forall i n ns.- (PosT i, NSRangeC (NatToPeanoT i) ns) =>+ (PosC i, NSRangeC (NatToPeanoT i) ns) => Lens' (FinMat ns) (Fin n) _finMatFin = lens (finMatFinGet @i @n @ns) (finMatFinSet @i @n @ns) -- | set the 'Fin' at index "i" for the FinMat finMatFinSet :: forall i n ns.- (PosT i, NSRangeC (NatToPeanoT i) ns) =>+ (PosC i, NSRangeC (NatToPeanoT i) ns) => FinMat ns -> Fin n -> FinMat ns-finMatFinSet fm@(FinMat _ ns) (Fin ind _) =+finMatFinSet fm@(FinMat _ ns) (Fin ind _) = forceRightP "finMatFinSet" $ let i = fromNP @i ps = finMatToNonEmpty fm in case setAt1 i ind ps of- Nothing -> programmError $ "finMatFinSet: index out of bounds: index is " ++ show i- Just ps1 -> frp $ nonEmptyToFinMat' ps1 ns+ Nothing -> Left $ "index out of bounds: index is " ++ show i+ Just ps1 -> nonEmptyToFinMat' ps1 ns {- | get the 'Fin' at index "i" from FinMat- must rely on FinMat to get "n at index i "which saves us pulling "n" from the typelevel ie we can omit PosT n+ must rely on FinMat to get "n at index i "which saves us pulling "n" from the typelevel ie we can omit PosC n -} finMatFinGet :: forall i n ns.- (PosT i, NSRangeC (NatToPeanoT i) ns) =>+ (PosC i, NSRangeC (NatToPeanoT i) ns) => FinMat ns -> Fin n-finMatFinGet fm@(FinMat _ ns) =+finMatFinGet fm@(FinMat _ ns) = forceRightP "finMatFinGet" $ let i = fromNP @i ps = finMatToNonEmpty fm in case (at1 i ps, at1 i ns) of- (Nothing, _) -> programmError "finMatFinGet: invalid index!"- (_, Nothing) -> programmError $ "finMatFinGet: FinMat is corrupt: doesnt have the index at " ++ show i ++ " " ++ show fm- (Just p, Just n) -> frp $ mkFin p n+ (Nothing, _) -> Left "invalid index!"+ (_, Nothing) -> Left $ "FinMat is corrupt: doesnt have the index at " ++ show i ++ " " ++ show fm+ (Just p, Just n) -> mkFin p n -- | lens for index 1 _i1 :: Lens' (FinMat (n ': ns)) (Fin n)@@ -394,3 +404,4 @@ -- | lens for index 10 _i10 :: Lens' (FinMat (n1 ': n2 ': n3 ': n4 ': n5 ': n6 ': n7 ': n8 ': n9 ': n ': ns)) (Fin n) _i10 = _finMatFin @10+
src/Cybus/Mat.hs view
@@ -20,6 +20,7 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE TupleSections #-} {- | Module : Cybus.Mat@@ -109,6 +110,10 @@ cartesian, pureMat, replicateMat,+ determinant,+-- determinantL,+-- cofactorsL,+deleteColumnL, -- * row operations deleteRow,@@ -159,6 +164,8 @@ concatMat, redim, reverseDim,+ rotateLeft,+ rotateRight, -- * subset and slicing SliceC (..),@@ -297,6 +304,7 @@ import Primus.Error import Primus.Fold import Primus.Lens+import Primus.List import Primus.NonEmpty import Primus.Num1 import Primus.One@@ -343,7 +351,7 @@ type Mat6 :: Nat -> Nat -> Nat -> Nat -> Nat -> Nat -> Type -> Type type Mat6 n m p q r s = Mat '[n, m, p, q, r, s] --- | convenient type synonym for specifying the dimensions of a matrix using the 'NN' type family+-- | convenient type synonym for specifying the dimensions of a matrix using each digit as a dimension type MatN :: Nat -> Type -> Type type MatN n = Mat (NN n) @@ -369,7 +377,7 @@ pattern MatIU v ps <- MatUnsafe v ps where- MatIU = frp .@ mkMat -- dont change this: frp is needed+ MatIU = frp .@ mkMat {-# COMPLETE MatU #-} @@ -383,7 +391,7 @@ pattern MatU v ps <- MatUnsafe v ps where- MatU = frp .@ mkMatC -- dont change this: frp is needed+ MatU = frp .@ mkMatC instance (Bounded a, Enum a) => Num1 (Mat ns a) where fromInteger1 = toEnumTraversable@@ -425,7 +433,7 @@ in MatU (V.replicate (productPInt ns) a) ns -- | creates a matrix of first dimension "n" by replicating the input matrix "n" times-replicateMat :: forall n n1 ns a. PosT n => Mat (n1 ': ns) a -> Mat (n ': n1 ': ns) a+replicateMat :: forall n n1 ns a. PosC n => Mat (n1 ': ns) a -> Mat (n ': n1 ': ns) a replicateMat (Mat v ns) = let n = fromNP @n in MatIU (V.concat (replicate (unP n) v)) (n N.<| ns)@@ -603,11 +611,11 @@ -- | updates a value in a matrix updateMat :: (a -> a) -> FinMat ns -> Mat ns a -> Mat ns a-updateMat f (FinMat i _) (Mat v ps) =+updateMat f (FinMat i _) (Mat v ps) = forceRightP "updateMat" $ do let (v1, v2) = V.splitAt i v- in case V.uncons v2 of- Just (a, v2') -> MatIU (v1 <> V.cons (f a) v2') ps- Nothing -> programmError $ "updateMat: i=" ++ show i+ case V.uncons v2 of+ Just (a, v2') -> mkMat (v1 <> V.cons (f a) v2') ps+ Nothing -> Left $ "i=" ++ show i -- | cons a value with a 1d matrix (.:) :: forall n a a'. a ~ a' => a -> Vec n a' -> Vec (1 GN.+ n) a'@@ -642,19 +650,19 @@ se2 (Mat v ps) = MatIU v (_1P N.<| ps) -- | create a 1d matrix from a list of values-vec :: forall n a. (HasCallStack, PosT n) => [a] -> Vec n a+vec :: forall n a. (HasCallStack, PosC n) => [a] -> Vec n a vec = mat @'[n] -- | create a 1d matrix from a list of values with the exact number of elements-vec' :: forall n a. (HasCallStack, PosT n) => [a] -> Vec n a+vec' :: forall n a. (HasCallStack, PosC n) => [a] -> Vec n a vec' = mat' @'[n] -- | create a 2d matrix from a list of values-mat2 :: forall n m a. (HasCallStack, PosT n, PosT m) => [a] -> Mat2 n m a+mat2 :: forall n m a. (HasCallStack, PosC n, PosC m) => [a] -> Mat2 n m a mat2 = mat @'[n, m] -- | create a 2d matrix from a list of values with the exact number of elements-mat2' :: forall n m a. (HasCallStack, PosT n, PosT m) => [a] -> Mat2 n m a+mat2' :: forall n m a. (HasCallStack, PosC n, PosC m) => [a] -> Mat2 n m a mat2' = mat' @'[n, m] -- | map each column@@ -863,61 +871,65 @@ instance n ~ n' => SliceC' '[n'] '[n] where sliceC' (FinMat i _) (Mat v _) = case v V.!? i of- Nothing -> programmError $ "sliceC': index " ++ show i ++ " out of bounds"+ Nothing -> programmError $ "sliceC' '[n] '[n]: index " ++ show i ++ " out of bounds" Just a -> a- sliceUpdateC' (FinMat i _) (Mat v ps) b =+ sliceUpdateC' (FinMat i _) (Mat v ps) b = forceRightP "sliceUpdateC' '[n] '[n]" $ do let (v1, v2) = V.splitAt i v- in case V.uncons v2 of- Just (_, v3) -> MatIU (v1 <> V.cons b v3) ps- Nothing -> programmError $ "sliceUpdateC': index " ++ show i ++ " out of bounds"+ case V.uncons v2 of+ Just (_, v3) -> mkMat (v1 <> V.cons b v3) ps+ Nothing -> Left $ "index " ++ show i ++ " out of bounds" instance n ~ n' => SliceC' '[n'] (n ': m ': ns) where- sliceC' (FinMat i _) (Mat v (_ :| ps)) =+ sliceC' (FinMat i _) (Mat v (_ :| ps)) = forceRightP "sliceC' '[n] (n ': m ': ns)" $ do case ps of- m : ns ->+ m : ns -> do let ps1 = m :| ns len1 = productPInt ps1- in MatIU (V.slice (i * len1) len1 v) ps1- [] -> programmError $ "sliceC': index " ++ show i ++ ": missing indices"+ mkMat (V.slice (i * len1) len1 v) ps1+ [] -> Left $ "index " ++ show i ++ ": missing indices" - sliceUpdateC' (FinMat i0 _) (Mat v w@(_ :| ps)) b =+ sliceUpdateC' (FinMat i0 _) (Mat v w@(_ :| ps)) b = forceRightP "sliceUpdateC' '[n] (n ': m ': ns)" $ do let len = productPInt ps i = i0 + 1 v1 = V.slice 0 ((i - 1) * len) v v2 = V.slice (i * len) (productPInt w - i * len) v- in MatIU (v1 <> mVec b <> v2) w+ mkMat (v1 <> mVec b <> v2) w instance (n ~ n', SliceC' (n1' ': ns') (n1 ': ns)) => SliceC' (n ': n1' ': ns') (n' ': n1 ': ns) where- sliceC' fm@(FinMat _ (_ :| n1ns')) w@(Mat _ (n :| _)) =+ sliceC' fm@(FinMat _ (_ :| n1ns')) w@(Mat _ (n :| _)) = forceRightP "sliceC' (n ': n1' ': ns')" $ do let x :| xs = finMatToNonEmpty fm i = unP x - 1- in case (xs, n1ns') of- (x1 : x1s, n1 : ns') ->- let fn1 = frp $ nonEmptyToFinMat' (x1 :| x1s) (n1 :| ns')- in sliceC' @(n1' ': ns') @(n1 ': ns) fn1 (sliceC' @'[n'] @(n ': n1 ': ns) (frp $ mkFinMat i (n :| [])) w)- ([], _) -> programmError "sliceC': missing ns' indices"- (_, []) -> programmError "sliceC': missing ns indices"- sliceUpdateC' fm@(FinMat _ (_ :| n1ns')) (Mat v w@(_ :| ps0)) b =+ case (xs, n1ns') of+ (x1 : x1s, n1 : ns') -> do+ fn1 <- nonEmptyToFinMat' (x1 :| x1s) (n1 :| ns')+ w1 <- mkFinMat i (n :| [])+ pure $ sliceC' @(n1' ': ns') @(n1 ': ns) fn1 (sliceC' @'[n'] @(n ': n1 ': ns) w1 w)+ ([], _) -> Left "missing ns' indices"+ (_, []) -> Left "missing ns indices"+ sliceUpdateC' fm@(FinMat _ (_ :| n1ns')) (Mat v w@(_ :| ps0)) b = forceRightP "sliceUpdateC' (n ': n1' ': ns')" $ do -- carve out the piece that is to be updated and pass that down then patch it all back together let x :| xs = finMatToNonEmpty fm i = unP x- in case (ps0, xs, n1ns') of- (_ : ns, x1 : x1s, n1 : ns') ->- let fn1 = frp $ nonEmptyToFinMat' (x1 :| x1s) (n1 :| ns')- ps1 = n1 :| ns+ case (ps0, xs, n1ns') of+ (_ : ns, x1 : x1s, n1 : ns') -> do+ fn1 <- nonEmptyToFinMat' (x1 :| x1s) (n1 :| ns')+ let ps1 = n1 :| ns len = productPInt ps1 v1 = V.slice 0 ((i - 1) * len) v v2 = V.slice (i * len) (productPInt w - i * len) v- m1 = MatIU (V.slice ((i - 1) * len) len v) ps1- mx = sliceUpdateC' @(n1' ': ns') @(n1 ': ns) fn1 m1 b- in MatIU (v1 <> mVec mx <> v2) w- ([], _, _) -> programmError "sliceUpdateC': missing matrix indices"- (_, [], _) -> programmError "sliceUpdateC': missing ns' indices"- (_, _, []) -> programmError "sliceUpdateC': missing finmat indices"+ m1 <- mkMat (V.slice ((i - 1) * len) len v) ps1+ let mx = sliceUpdateC' @(n1' ': ns') @(n1 ': ns) fn1 m1 b+ mkMat (v1 <> mVec mx <> v2) w+ ([], _, _) -> Left "missing matrix indices"+ (_, [], _) -> Left "missing ns' indices"+ (_, _, []) -> Left "missing finmat indices" -instance (GL.TypeError ( 'GL.Text "SliceC': too many indices ns': length ns' > length ns")) => SliceC' (n' ': n1' ': ns') '[n] where+instance+ GL.TypeError ( 'GL.Text "SliceC': too many indices ns': length ns' > length ns") =>+ SliceC' (n' ': n1' ': ns') '[n]+ where sliceC' = compileError "sliceC'" sliceUpdateC' = compileError "sliceUpdateC'" @@ -999,27 +1011,27 @@ sliceC = compileError "SliceC:sliceC" sliceUpdateC = compileError "SliceC:sliceUpdateC" -instance FinT i n => SliceC '[i] '[n] where+instance FinC i n => SliceC '[i] '[n] where sliceC (Mat v _) = let i = fromN @i - 1 in case v V.!? i of Nothing -> programmError $ "sliceC: index " ++ show i ++ " out of bounds" Just a -> a- sliceUpdateC (Mat v ps) b =+ sliceUpdateC (Mat v ps) b = forceRightP "sliceC' '[i] '[n]" $ do let i = fromN @i - 1 (v1, v2) = V.splitAt i v- in case V.uncons v2 of- Just (_, v3) -> MatIU (v1 <> V.cons b v3) ps- Nothing -> programmError $ "sliceUpdateC: index " ++ show i ++ " out of bounds"-instance FinT i n => SliceC '[i] (n ': m ': ns) where- sliceC (Mat v (_ :| ps)) =+ case V.uncons v2 of+ Just (_, v3) -> mkMat (v1 <> V.cons b v3) ps+ Nothing -> Left $ "index " ++ show i ++ " out of bounds"+instance FinC i n => SliceC '[i] (n ': m ': ns) where+ sliceC (Mat v (_ :| ps)) = forceRightP "sliceC' '[i] (n ': m ': ns)" $ do case ps of- m : ns ->+ m : ns -> do let i = fromN @i - 1 ps1 = m :| ns len1 = productPInt ps1- in MatIU (V.slice (i * len1) len1 v) ps1- [] -> programmError $ "sliceUpdateC: index " ++ show (fromN @i) ++ ": missing indices"+ mkMat (V.slice (i * len1) len1 v) ps1+ [] -> Left $ "index " ++ show (fromN @i) ++ ": missing indices" sliceUpdateC (Mat v w@(_ :| ps)) b = let i = fromN @i@@ -1029,26 +1041,29 @@ in MatIU (v1 <> mVec b <> v2) w instance- (FinT i n, SliceC (i1 ': is) (n1 ': ns)) =>+ (FinC i n, SliceC (i1 ': is) (n1 ': ns)) => SliceC (i ': i1 ': is) (n ': n1 ': ns) where sliceC w = sliceC @(i1 ': is) @(n1 ': ns) (sliceC @'[i] @(n ': n1 ': ns) w)- sliceUpdateC (Mat v w@(_ :| ps0)) b =+ sliceUpdateC (Mat v w@(_ :| ps0)) b = forceRightP "sliceUpdateC' (i ': i1 ': is) (n ': m ': ns)" $ do -- carve out the piece that is to be updated and pass that down then patch it all back together case ps0 of- n1 : ns ->+ n1 : ns -> do let i = fromN @i ps1 = n1 :| ns len = productPInt ps1 v1 = V.slice 0 ((i - 1) * len) v v2 = V.slice (i * len) (productPInt w - i * len) v- m1 = MatIU (V.slice ((i - 1) * len) len v) ps1- mx = sliceUpdateC @(i1 ': is) @(n1 ': ns) m1 b- in MatIU (v1 <> mVec mx <> v2) w- [] -> programmError $ "sliceUpdateC: index " ++ show (fromN @i) ++ ": missing indices"+ m1 <- mkMat (V.slice ((i - 1) * len) len v) ps1+ let mx = sliceUpdateC @(i1 ': is) @(n1 ': ns) m1 b+ mkMat (v1 <> mVec mx <> v2) w+ [] -> Left $ "index " ++ show (fromN @i) ++ ": missing indices" -instance (GL.TypeError ( 'GL.Text "too many indices 'is': length is > length ns")) => SliceC (i ': i1 ': is) '[n] where+instance+ GL.TypeError ( 'GL.Text "too many indices 'is': length is > length ns") =>+ SliceC (i ': i1 ': is) '[n]+ where sliceC = compileError "sliceC (2)" sliceUpdateC = compileError "sliceUpdateC (2)" @@ -1062,7 +1077,7 @@ -- | a lens for acccessing a column _col :: forall (i :: Nat) n m ns a.- (FinT i m) =>+ (FinC i m) => Lens' (Mat (n ': m ': ns) a) (Mat (n ': ns) a) _col = _transposeMat . _row @i @@ -1107,14 +1122,14 @@ forall n m ns a. Mat (n ': m ': ns) a -> Vec n (Mat (m ': ns) a)-rows w@(Mat _ (n :| ps)) =+rows w@(Mat _ (n :| ps)) = forceRightP "rows" $ case ps of- m : ns ->- let zs = frp $ chunkNVMat (unitsF @[] n) (m :| ns) w- in MatIU (V.fromList zs) (n :| [])- [] -> programmError "rows: missing indices"+ m : ns -> do+ zs <- chunkNVMat (unitsF @[] n) (m :| ns) w+ mkMat (V.fromList zs) (n :| [])+ [] -> Left "missing indices" --- | unbust from rows @see 'rows'+-- | unbust from rows see 'rows' unrows :: forall n m ns a. Vec n (Mat (m ': ns) a) ->@@ -1183,14 +1198,14 @@ Mat2 n m a -> Mat2 m p b -> Mat2 n p d-dot f g w1@(Mat _ (n :| ps1)) w2@(Mat _ (_ :| ps2)) =+dot f g w1@(Mat _ (n :| ps1)) w2@(Mat _ (_ :| ps2)) = forceRightP "dot" $ case (ps1, ps2) of- ([m], [p]) ->- let z1 = frp $ chunkNLen1 n m w1- z2 = N.transpose $ frp $ chunkNLen1 m p w2- w = liftA2 ((g . frp) .@ zipWithExact f) z1 z2- in MatIU (V.fromList $ N.toList w) (n :| [p])- o -> programmError $ "dot: missing indices " ++ show o+ ([m], [p]) -> do+ z1 <- chunkNLen1 n m w1+ z2 <- N.transpose <$> chunkNLen1 m p w2+ w <- sequenceA $ liftA2 (fmap g .@ zipWithExact f) z1 z2+ mkMat (V.fromList $ N.toList w) (n :| [p])+ o -> Left $ "missing indices " ++ show o -- | multiply two matrices together multMat ::@@ -1204,7 +1219,7 @@ -- | delete a row deleteRow :: forall (i :: Nat) (n :: Nat) (ns :: [Nat]) a.- FinT i (1 GN.+ n) =>+ FinC i (1 GN.+ n) => Mat (1 GN.+ n ': ns) a -> Mat (n ': ns) a deleteRow = deleteRow' (finC @i @(1 GN.+ n))@@ -1215,18 +1230,18 @@ Fin (1 GN.+ n) -> Mat (1 GN.+ n ': ns) a -> Mat (n ': ns) a-deleteRow' (Fin (Pos i) _) (Mat v (sn :| ps)) =- let n = frp $ predP sn- n1 = productPInt ps+deleteRow' (Fin (Pos i) _) (Mat v (sn :| ps)) = forceRightP "deleteRow'" $ do+ n <- predP sn+ let n1 = productPInt ps s = (i - 1) * n1 v1 = V.slice 0 s v v2 = V.slice (s + n1) (productPInt (sn :| ps) - s - n1) v- in MatIU (v1 <> v2) (n :| ps)+ mkMat (v1 <> v2) (n :| ps) -- | delete a row from a matrix insertRow :: forall i n m ns a.- FinT i (1 GN.+ n) =>+ FinC i (1 GN.+ n) => Mat (m ': ns) a -> Mat (n ': m ': ns) a -> Mat (1 GN.+ n ': m ': ns) a@@ -1248,7 +1263,7 @@ -- | delete a column from a matrix (2d or higher) deleteCol :: forall (i :: Nat) (n :: Nat) (n1 :: Nat) ns a.- FinT i (1 GN.+ n1) =>+ FinC i (1 GN.+ n1) => Mat (n ': (1 GN.+ n1) ': ns) a -> Mat (n ': n1 ': ns) a deleteCol = deleteCol' (finC @i @(1 GN.+ n1))@@ -1264,7 +1279,7 @@ -- | insert a column into a mat (2d and above) insertCol :: forall (i :: Nat) (n :: Nat) (n1 :: Nat) ns a.- FinT i (1 GN.+ n1) =>+ FinC i (1 GN.+ n1) => Mat (n ': ns) a -> Mat (n ': n1 ': ns) a -> Mat (n ': (1 GN.+ n1) ': ns) a@@ -1282,7 +1297,7 @@ -- | swaps mat rows (1d or more) swapRow :: forall (i :: Nat) (j :: Nat) (n :: Nat) ns a.- (FinT i n, FinT j n) =>+ (FinC i n, FinC j n) => Mat (n ': ns) a -> Mat (n ': ns) a swapRow = swapRow' (finC @i) (finC @j)@@ -1312,7 +1327,7 @@ -- | swaps mat rows (2d or more) swapCol :: forall (i :: Nat) (j :: Nat) (n :: Nat) (n1 :: Nat) ns a.- (FinT i n1, FinT j n1) =>+ (FinC i n1, FinC j n1) => Mat (n ': n1 ': ns) a -> Mat (n ': n1 ': ns) a swapCol = swapCol' (finC @i) (finC @j)@@ -1358,20 +1373,20 @@ Mat (n ': m ': ns) a -> Mat (n ': m' ': ns) a -> Mat (n ': (m GN.+ m') ': ns) a-appendH w@(Mat _ (n :| ps)) w1@(Mat _ (n' :| ps1))- | n == n' =+appendH w@(Mat _ (n :| ps)) w1@(Mat _ (n' :| ps1)) = forceRightP "appendH" $+ if n == n' then case (ps, ps1) of- ([], _) -> programmError "appendH:lhs missing indices"- (_, []) -> programmError "appendH:rhs missing indices"+ ([], _) -> Left "lhs missing indices"+ (_, []) -> Left "rhs missing indices" (m : ns, m' : ns')- | ns == ns' ->- let x1 = frp $ chunkNV (unitsF n) (productP (m :| ns)) (mVec w)- x2 = frp $ chunkNV (unitsF @[] n) (productP (m' :| ns')) (mVec w1)- ret = frp $ zipWithExact (<>) x1 x2- ps2 = n :| ([m +! m'] <> ns)- in MatIU (V.concat ret) ps2- | otherwise -> programmError $ "appendH:ns/=ns' " ++ show (ns, ns')- | otherwise = programmError $ "appendH: n/=n' " ++ show (n, n')+ | ns == ns' -> do+ x1 <- chunkNV (unitsF n) (productP (m :| ns)) (mVec w)+ x2 <- chunkNV (unitsF @[] n) (productP (m' :| ns')) (mVec w1)+ ret <- zipWithExact (<>) x1 x2+ let ps2 = n :| ([m +! m'] <> ns)+ mkMat (V.concat ret) ps2+ | otherwise -> Left $ "ns/=ns' " ++ show (ns, ns')+ else Left $ "n/=n' " ++ show (n, n') -- | return a mat as a permutation of a list (1d only) todo: extend to multidimensions permutationsMat :: forall n a. Vec n a -> Mat2 (FacT n) n a@@ -1440,7 +1455,7 @@ -- | convert a matrix to a nested tuple type MatTupleT :: [Nat] -> Type -> Type type family MatTupleT ns a where- MatTupleT '[] _ = GL.TypeError ('GL.Text "MatTupleT '[]: undefined for empty indices")+ MatTupleT '[] _ = GL.TypeError ( 'GL.Text "MatTupleT '[]: undefined for empty indices") MatTupleT '[n] a = ListTupleT n a MatTupleT (n ': n1 ': ns) a = ListTupleT n (MatTupleT (n1 ': ns) a) @@ -1464,14 +1479,14 @@ -- | traversal over a well-formed nested tuple Traversal (MatTupleT ns a) (MatTupleT ns b) a b -instance GL.TypeError ('GL.Text "MatTupleC '[]: undefined for empty indices") => MatTupleC '[] a where+instance GL.TypeError ( 'GL.Text "MatTupleC '[]: undefined for empty indices") => MatTupleC '[] a where toTupleC = compileError "MatTupleC:toTupleC" fromTupleC = compileError "MatTupleC:fromTupleC" fmapTupleMatC = compileError "MatTupleC:fmapTupleMatC" traversalTupleMatC = compileError "MatTupleC:traversalTupleMatC" instance ListTupleCInternal n => MatTupleC '[n] a where- toTupleC = toTupleCInternal+ toTupleC = toTupleCInternal fromTupleC = fromTupleCInternal fmapTupleMatC = fmapTupleInternal traversalTupleMatC = traversalTupleCInternal@@ -1562,22 +1577,22 @@ -- | transpose a 2d or larger matrix transposeMat :: forall n m ns a. Mat (n ': m ': ns) a -> Mat (m ': n ': ns) a-transposeMat w@(Mat _ (n :| ps)) =+transposeMat w@(Mat _ (n :| ps)) = forceRightP "transposeMat" $ case ps of- [] -> programmError "transposeMat"- m : ns ->- let ys = frp $ chunkNLen1 n (productP (m :| ns)) w- zs = N.transpose $ N.map (chunksOf1 (productP ns)) ys- in MatIU (V.fromList $ N.toList $ sconcat $ sconcat zs) (m :| (n : ns))+ [] -> Left "transposeMat"+ m : ns -> do+ ys <- chunkNLen1 n (productP (m :| ns)) w+ let zs = N.transpose $ N.map (chunksOf1 (productP ns)) ys+ mkMat (V.fromList $ N.toList $ sconcat $ sconcat zs) (m :| (n : ns)) -- | validate and convert from a nested list to a matrix-nestedListToMatValidated :: forall ns x a. (x ~ ListNST ns a, ValidateNestedListC x (ValidateNestedListT x), MatConvertersC ns) => ListNST ns a -> Either String (Mat ns a)+nestedListToMatValidated :: forall ns a x. (x ~ ListNST ns a, ValidateNestedListC x (ValidateNestedListT x), MatConvertersC ns) => ListNST ns a -> Either String (Mat ns a) nestedListToMatValidated w = do _ <- validateNestedList w nestedListToMatC w -- | validate and convert from a nested nonempty list to a matrix-nestedNonEmptyToMatValidated :: forall ns x a. (x ~ NonEmptyNST ns a, ValidateNestedNonEmptyC x (ValidateNestedNonEmptyT x), MatConvertersC ns) => NonEmptyNST ns a -> Either String (Mat ns a)+nestedNonEmptyToMatValidated :: forall ns a x. (x ~ NonEmptyNST ns a, ValidateNestedNonEmptyC x (ValidateNestedNonEmptyT x), MatConvertersC ns) => NonEmptyNST ns a -> Either String (Mat ns a) nestedNonEmptyToMatValidated w = do _ <- validateNestedNonEmpty w nestedNonEmptyToMatC w@@ -1602,7 +1617,7 @@ -- | convert a nested nonempty list to a 'Mat' nestedNonEmptyToMatC :: NonEmptyNST ns a -> Either String (Mat ns a) -instance GL.TypeError ('GL.Text "MatConvertersC '[]: undefined for empty indices") => MatConvertersC '[] where+instance GL.TypeError ( 'GL.Text "MatConvertersC '[]: undefined for empty indices") => MatConvertersC '[] where matToNestedVecC = compileError "MatConvertersC" nestedVecToMatC = compileError "MatConvertersC" matToNestedListC = compileError "MatConvertersC"@@ -1610,14 +1625,14 @@ nestedListToMatC = compileError "MatConvertersC" nestedNonEmptyToMatC = compileError "MatConvertersC" -instance PosT n => MatConvertersC '[n] where+instance PosC n => MatConvertersC '[n] where matToNestedVecC = id nestedVecToMatC = id matToNestedListC = toListMat matToNestedNonEmptyC = toNonEmptyMat nestedListToMatC = matImpl True nestedNonEmptyToMatC = matImpl True . N.toList-instance (PosT n, MatConvertersC (m ': ns)) => MatConvertersC (n ': m ': ns) where+instance (PosC n, MatConvertersC (m ': ns)) => MatConvertersC (n ': m ': ns) where matToNestedVecC lst = fmap matToNestedVecC (rows @n lst) nestedVecToMatC lst@(Mat _ (n :| _)) = let zs@(Mat _ (m :| ns) :| _) = toNonEmptyMat $ fmap (nestedVecToMatC @(m ': ns)) lst@@ -1631,7 +1646,7 @@ nestedNonEmptyToMatC w = nonEmptyMatsToMat =<< traverse (nestedNonEmptyToMatC @(m ': ns)) w -- | create a matrix of one dimension higher from rows of a sub matrix-nonEmptyMatsToMat :: forall n m ns a t. (Foldable1 t, PosT n) => t (Mat (m ': ns) a) -> Either String (Mat (n ': m ': ns) a)+nonEmptyMatsToMat :: forall n m ns a t. (Foldable1 t, PosC n) => t (Mat (m ': ns) a) -> Either String (Mat (n ': m ': ns) a) nonEmptyMatsToMat (toNonEmpty -> xs@(Mat _ ps :| _)) = do let n = fromNP @n ret <- lengthExact1 n xs@@ -1640,29 +1655,29 @@ -- | converts mat dimensions to a nested list type MatToNestedVecT :: [Nat] -> Type -> Type type family MatToNestedVecT ns a where- MatToNestedVecT '[] _ = GL.TypeError ('GL.Text "MatToNestedVecT '[]: undefined for empty indices")+ MatToNestedVecT '[] _ = GL.TypeError ( 'GL.Text "MatToNestedVecT '[]: undefined for empty indices") MatToNestedVecT '[n] a = Vec n a MatToNestedVecT (n ': n1 ': ns) a = Vec n (MatToNestedVecT (n1 ': ns) a) --- | type synonym for the result of nesting a matrix: @see 'toND'+-- | type synonym for the result of nesting a matrix: see 'toND' type MatToNDT :: Nat -> [Nat] -> Type -> Type type MatToNDT i ns a = Mat (MatToMatNTA (NatToPeanoT i) ns) (Mat (MatToMatNTB (NatToPeanoT i) ns) a) -- | create a nested matrix going "i" levels down: noop is not supported ie 4D matrix to a 4D matrix matToNDImpl :: forall (i :: Nat) (ns :: [Nat]) a.- PosT i =>+ PosC i => Mat ns a -> MatToNDT i ns a-matToNDImpl w@(Mat _ ps) =+matToNDImpl w@(Mat _ ps) = forceRightP "matToNDImpl" $ let i = fromNP @i (ps1, bs) = splitAt1 i ps in case bs of- y : ys ->+ y : ys -> do let ps2 = y :| ys- xs = frp $ chunkNVMat (unitsF (productP ps1)) ps2 w- in MatIU (V.fromList xs) ps1- [] -> programmError "toND:missing indices to the right"+ xs <- chunkNVMat (unitsF (productP ps1)) ps2 w+ mkMat (V.fromList xs) ps1+ [] -> Left "missing indices to the right" type MatToMatNTA :: Peano -> [Nat] -> [Nat] type family MatToMatNTA i ns where@@ -1686,19 +1701,19 @@ GL.TypeError ( 'GL.Text "MatToMatNTB: depth is more than the number of indices") MatToMatNTB ( 'S ( 'S i)) (_ ': m ': ns) = MatToMatNTB ( 'S i) (m ': ns) --- | create a nd matrix using a Nat @see 'toND-toND :: forall i ns a. i <=! i => Mat ns a -> MatToNDT i ns a+-- | create a nd matrix using a Nat see 'toND+toND :: forall i ns a. PosC i => Mat ns a -> MatToNDT i ns a toND = matToNDImpl @i --- | create a nested 1d matrix @see 'toND+-- | create a nested 1d matrix see 'toND toVec :: Mat ns a -> MatToNDT 1 ns a toVec = toND @1 --- | create a nested 2d matrix @see 'toND+-- | create a nested 2d matrix see 'toND toMat2 :: Mat ns a -> MatToNDT 2 ns a toMat2 = toND @2 --- | create a nested 3d matrix @see 'toND+-- | create a nested 3d matrix see 'toND toMat3 :: Mat ns a -> MatToNDT 3 ns a toMat3 = toND @3 @@ -1713,13 +1728,13 @@ -- | gets the diagonal elements of a 2d or greater square matrix: the diagonal of a n * n * ns matrix results in a n * ns matrix diagonal :: Mat (n ': n ': ns) a -> Mat (n ': ns) a-diagonal (Mat v (n :| ps)) =+diagonal (Mat v (n :| ps)) = forceRightP "diagonal" $ case ps of- _n : ns ->+ _n : ns -> do let len = productPInt ns xs = map (\i -> V.slice (i * (unP n + 1) * len) len v) [0 .. unP n - 1]- in MatIU (V.concat xs) (n :| ns)- [] -> programmError "diagonal: missing indices"+ mkMat (V.concat xs) (n :| ns)+ [] -> Left "missing indices" -- | take a subset of a matrix using the start and end rows subsetRows ::@@ -1727,13 +1742,13 @@ DiffTC i j n => Mat (n ': ns) a -> Mat (DiffT i j n ': ns) a-subsetRows (Mat v (_ :| ns)) =+subsetRows (Mat v (_ :| ns)) = forceRightP "subsetRows" $ do let i = fromNP @i j = fromNP @j n1 = (unP i - 1) * productPInt ns- n' = frp $ withOp2 ((-) . (+ 1)) j i- ps1 = n' :| ns- in MatIU (V.slice n1 (productPInt ps1) v) ps1+ n' <- withOp2 ((-) . (+ 1)) j i+ let ps1 = n' :| ns+ mkMat (V.slice n1 (productPInt ps1) v) ps1 -- todo use FinMat versions of subsetRows and subsetCols ie not just typelevel: need typelevel for the count of rows/cols so no point @@ -1764,7 +1779,7 @@ -- | specialised version of 'readMat' for 'Vec' readVec :: ( MatConvertersC '[n]- , PosT n+ , PosC n , Read [a] ) => ReadS (Vec n a)@@ -1773,8 +1788,8 @@ -- | specialised version of 'readMat' for 'Mat2' readMat2 :: ( MatConvertersC '[n, m]- , PosT n- , PosT m+ , PosC n+ , PosC m , Read [[a]] ) => ReadS (Mat2 n m a)@@ -1940,105 +1955,105 @@ _r10 :: Lens' s a -- | lens into the first row in a 2d or greater matrix-instance FinT 1 n => Row1 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 1 n => Row1 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r1 = _row @1 -- | lens into the first element in a 1d matrix-instance FinT 1 n => Row1 (Vec n a) a where+instance FinC 1 n => Row1 (Vec n a) a where _r1 = _row @1 -instance (FinT 2 n) => Row2 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 2 n => Row2 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r2 = _row @2 -instance (FinT 2 n) => Row2 (Vec n a) a where+instance FinC 2 n => Row2 (Vec n a) a where _r2 = _row @2 -instance (FinT 3 n) => Row3 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 3 n => Row3 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r3 = _row @3 -instance (FinT 3 n) => Row3 (Vec n a) a where+instance FinC 3 n => Row3 (Vec n a) a where _r3 = _row @3 -instance (FinT 4 n) => Row4 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 4 n => Row4 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r4 = _row @4 -instance (FinT 4 n) => Row4 (Vec n a) a where+instance FinC 4 n => Row4 (Vec n a) a where _r4 = _row @4 -instance (FinT 5 n) => Row5 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 5 n => Row5 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r5 = _row @5 -instance (FinT 5 n) => Row5 (Vec n a) a where+instance FinC 5 n => Row5 (Vec n a) a where _r5 = _row @5 -instance (FinT 6 n) => Row6 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 6 n => Row6 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r6 = _row @6 -instance (FinT 6 n) => Row6 (Vec n a) a where+instance FinC 6 n => Row6 (Vec n a) a where _r6 = _row @6 -instance (FinT 7 n) => Row7 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 7 n => Row7 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r7 = _row @7 -instance (FinT 7 n) => Row7 (Vec n a) a where+instance FinC 7 n => Row7 (Vec n a) a where _r7 = _row @7 -instance (FinT 8 n) => Row8 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 8 n => Row8 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r8 = _row @8 -instance (FinT 8 n) => Row8 (Vec n a) a where+instance FinC 8 n => Row8 (Vec n a) a where _r8 = _row @8 -instance (FinT 9 n) => Row9 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 9 n => Row9 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r9 = _row @9 -instance (FinT 9 n) => Row9 (Vec n a) a where+instance FinC 9 n => Row9 (Vec n a) a where _r9 = _row @9 -instance (FinT 10 n) => Row10 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where+instance FinC 10 n => Row10 (Mat (n ': m ': ns) a) (Mat (m ': ns) a) where _r10 = _row @10 -instance (FinT 10 n) => Row10 (Vec n a) a where+instance FinC 10 n => Row10 (Vec n a) a where _r10 = _row @10 -- | lens into column 1 of a matrix-_c1 :: FinT 1 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c1 :: FinC 1 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c1 = _col @1 -- | lens into column 2 of a matrix-_c2 :: FinT 2 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c2 :: FinC 2 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c2 = _col @2 -- | lens into column 3 of a matrix-_c3 :: FinT 3 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c3 :: FinC 3 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c3 = _col @3 -- | lens into column 4 of a matrix-_c4 :: FinT 4 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c4 :: FinC 4 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c4 = _col @4 -- | lens into column 5 of a matrix-_c5 :: FinT 5 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c5 :: FinC 5 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c5 = _col @5 -- | lens into column 6 of a matrix-_c6 :: FinT 6 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c6 :: FinC 6 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c6 = _col @6 -- | lens into column 7 of a matrix-_c7 :: FinT 7 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c7 :: FinC 7 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c7 = _col @7 -- | lens into column 8 of a matrix-_c8 :: FinT 8 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c8 :: FinC 8 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c8 = _col @8 -- | lens into column 9 of a matrix-_c9 :: FinT 9 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c9 :: FinC 9 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c9 = _col @9 -- | lens into column 10 of a matrix-_c10 :: FinT 10 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a)+_c10 :: FinC 10 m => Lens' (Mat (n ': (m : ns)) a) (Mat (n ': ns) a) _c10 = _col @10 -- | marker representing the last value in a 1d matrix ie singleton@@ -2099,11 +2114,11 @@ where consMat = iso- ( \(Mat v0 (sn :| ps)) ->- let n = frp $ predP sn- in case V.uncons v0 of -- stay within Vector- Nothing -> programmError "consMat '[1 GN.+ n]: no data"- Just (a, v) -> (a, MatIU v (n :| ps))+ ( \(Mat v0 (sn :| ps)) -> forceRightP "consMat '[n]" $ do+ n <- predP sn+ case V.uncons v0 of -- stay within Vector+ Nothing -> Left "no data"+ Just (a, v) -> (a,) <$> mkMat v (n :| ps) ) (\(a, Mat v (p :| ps)) -> MatIU (V.cons a v) (succP p :| ps)) @@ -2118,10 +2133,10 @@ where consMat = iso- ( \(Mat v (_ :| ps)) ->+ ( \(Mat v (_ :| ps)) -> forceRightP "consMat '(1 ': n1 ': ns)" $ case ps of- m : ns -> (MatIU v (m :| ns), EofN)- [] -> programmError "consMat (1 ': m ': ns): missing indices"+ m : ns -> (,EofN) <$> mkMat v (m :| ns)+ [] -> Left "missing indices" ) (\(Mat v ps, EofN) -> MatIU v (_1P N.<| ps)) @@ -2136,17 +2151,15 @@ where consMat = iso- ( \(Mat v (sn :| ps)) ->+ ( \(Mat v (sn :| ps)) -> forceRightP "consMat '(n ': m ': ns)" $ do case ps of- m : ns ->- let n = frp $ predP sn- ps1 = m :| ns+ m : ns -> do+ n <- predP sn+ let ps1 = m :| ns ps2 = n :| (m : ns) (v1, v2) = V.splitAt (productPInt ps1) v- in ( MatIU v1 ps1- , MatIU v2 ps2- )- [] -> programmError "consMat:(1 GN.+ n ': m ': ns): missing indices"+ liftA2 (,) (mkMat v1 ps1) (mkMat v2 ps2)+ [] -> Left "missing indices" ) (\(Mat v1 _, Mat v2 (p2 :| ps2)) -> MatIU (v1 <> v2) (succP p2 :| ps2)) @@ -2180,22 +2193,22 @@ where snocMat = iso- ( \(Mat v0 (sn :| ps)) ->- let n = frp $ predP sn- in case V.unsnoc v0 of- Nothing -> programmError "snocMat '[1 GN.+ n]: no data"- Just (v, a) -> (MatIU v (n :| ps), a)+ ( \(Mat v0 (sn :| ps)) -> forceRightP "snocMat '[n]" $ do+ n <- predP sn+ case V.unsnoc v0 of+ Nothing -> Left "no data"+ Just (v, a) -> (,a) <$> mkMat v (n :| ps) ) (\(Mat v (p :| ps), a) -> MatIU (V.snoc v a) (succP p :| ps)) instance {-# OVERLAPPING #-} SnocMatC (1 ': n1 ': ns) a b where snocMat = iso- ( \(Mat v (_ :| ps)) ->+ ( \(Mat v (_ :| ps)) -> forceRightP "snocMat '(1 ': n1 ': ns)" $ do case ps of m : ns ->- (EofN, MatIU v (m :| ns))- [] -> programmError "snocMat '[1 GN.+ n]: missing indices"+ (EofN,) <$> mkMat v (m :| ns)+ [] -> Left "missing indices" ) (\(EofN, Mat v ps) -> MatIU v (_1P N.<| ps)) @@ -2208,17 +2221,15 @@ where snocMat = iso- ( \(Mat v (sn :| ps)) ->+ ( \(Mat v (sn :| ps)) -> forceRightP "snocMat '(n ': m ': ns)" $ do case ps of- m : ns ->- let n = frp $ predP sn- ps1 = m :| ns+ m : ns -> do+ n <- predP sn+ let ps1 = m :| ns ps2 = n :| (m : ns) (v2, v1) = V.splitAt (productPInt ps2) v- in ( MatIU v2 ps2- , MatIU v1 ps1- )- [] -> programmError "snocMat:(1 GN.+ n ': m ': ns): missing indices"+ liftA2 (,) (mkMat v2 ps2) (mkMat v1 ps1)+ [] -> Left "missing indices" ) (\(Mat v1 (p1 :| ps1), Mat v2 _) -> MatIU (v1 <> v2) (succP p1 :| ps1)) @@ -2233,13 +2244,13 @@ -- | get a row from a matrix using a concrete index see '_row'' indexRow :: Fin n -> Mat (n ': m ': ns) a -> Mat (m ': ns) a-indexRow (Fin (Pos i) _n) (Mat v (_ :| ps)) =+indexRow (Fin (Pos i) _n) (Mat v (_ :| ps)) = forceRightP "indexRow" $ case ps of- m : ns ->+ m : ns -> do let s = (i - 1) * len len = productPInt (m :| ns)- in MatIU (V.slice s len v) (m :| ns)- [] -> programmError "indexRow: missing indices"+ mkMat (V.slice s len v) (m :| ns)+ [] -> Left "missing indices" -- | 'Data.List.scanr' for a vector scanrVec :: forall n a b. (a -> b -> b) -> b -> Vec n a -> Vec (n GN.+ 1) b@@ -2251,14 +2262,14 @@ scanlVec f c (Mat v (p :| ps)) = MatIU (V.scanl' f c v) (succP p :| ps) -{- | @see 'Data.Vector.postscanr''+{- | see 'Data.Vector.postscanr'' concrete version of 'Primus.Fold.postscanr -} postscanrMat :: forall ns a b. (a -> b -> b) -> b -> Mat ns a -> Mat ns b postscanrMat f c (Mat v ps) = MatIU (V.postscanr' f c v) ps -{- | @see 'Data.Vector.postscanl''+{- | see 'Data.Vector.postscanl'' concrete version of 'Primus.Fold.postscanl' -} postscanlMat :: forall ns a b. (b -> a -> b) -> b -> Mat ns a -> Mat ns b@@ -2304,3 +2315,54 @@ -- | matrix of dimension 10 dim10 :: Mat '[n, m, p, q, r, s, t, u, v, w] a -> Mat '[n, m, p, q, r, s, t, u, v, w] a dim10 = id++-- | left rotate a matrix+rotateLeft :: Mat2 n m a -> Mat2 m n a+rotateLeft = unrows . sequence1 . fmap reverseT . rows++-- | right rotate a matrix+rotateRight :: Mat2 n m a -> Mat2 m n a+rotateRight = unrows . fmap reverseT . sequence1 . rows++cofactorsL :: forall a . Pos -> [a] -> [(a, [a])]+cofactorsL n xs+ | n <= _2P = programmError $ "cofactorsL: n is too small: must be greater than 2 but found " ++ show n+ | len /= len' = programmError $ "cofactorsL: wrong length: expected " ++ show len' ++ " but found " ++ show len+ | otherwise =+ let (h,t) = splitAt (unP n) xs+ in foldl' (\z (i,a) -> (a,deleteColumnL n i t):z) [] (zip [0..] h)+ where len = length xs+ len' = unP (n *! n)++-- | delete column "i" from a list of width "n"+deleteColumnL :: forall a . Pos -> Int -> [a] -> [a]+deleteColumnL (Pos n) i ys =+ let (as,bs) = splitAt i ys+ in as <> concat (L.unfoldr g bs)+ where+ g :: [a] -> Maybe ([a],[a])+ g = list Nothing (\_ -> Just . splitAt (n-1))++determinantL :: forall a . Num a => Pos -> [a] -> a+determinantL n m0+ | len /= unP (n *! n) = programmError $ "determinantL: wrong length n=" ++ show n ++ " m=" ++ show len+ | otherwise =+ case m0 of+ [a] -> a+ [a,b,c,d] -> a * d - b * c+ _o ->+ snd $ foldl' f (True, 0) (cofactorsL n m0)+ where+ f :: (Bool, a) -> (a, [a]) -> (Bool, a)+ f (sgn, tot) (a, m) =+ let val = bool id negate sgn a * determinantL (frp $ predP n) m+ in (not sgn, tot + val)+ len = length m0++-- | get the determinant of a matrix+determinant :: Num a => Mat2 n n a -> a+determinant (Mat v (n :| _)) =+ bool negate id (n <= _2P) $ determinantL n (V.toList v)+++
src/Cybus/NatHelper.hs view
@@ -74,14 +74,14 @@ import Data.Pos import Data.Proxy import qualified GHC.TypeLits as GL-import GHC.TypeNats (Nat)+import GHC.TypeNats (Nat,KnownNat) import qualified GHC.TypeNats as GN import Primus.Error import Primus.Fold import Primus.List import Primus.NonEmpty import Primus.One-import qualified Primus.TypeLevel as TP (FailUnless)+import Primus.TypeLevel (FailUnless) -- | get the factorial of a 'Nat' type FacT :: Nat -> Nat@@ -93,7 +93,7 @@ -- | constraint for ensuring that "i" <= "n" type (<=!) :: Nat -> Nat -> Constraint type i <=! n =- ( TP.FailUnless+ ( FailUnless (i GN.<=? n) ( 'GL.Text "i>n" 'GL.:<>: 'GL.Text ": i="@@ -101,13 +101,13 @@ 'GL.:<>: 'GL.Text " n=" 'GL.:<>: 'GL.ShowType n )- , PosT i+ , PosC i ) -- | constraint for ensuring that "i" <= "n" with a custom error message type LTEQT :: GL.ErrorMessage -> Nat -> Nat -> Constraint type LTEQT msg i n =- ( TP.FailUnless+ ( FailUnless (i GN.<=? n) ( 'GL.Text "i>n" 'GL.:<>: 'GL.Text ": i="@@ -116,13 +116,13 @@ 'GL.:<>: 'GL.ShowType n 'GL.:<>: msg )- , PosT i+ , PosC i ) -- | constraint for ensuring that "i" <= "n" type (<!) :: Nat -> Nat -> Constraint type i <! n =- ( TP.FailUnless+ ( FailUnless (i GN.+ 1 GN.<=? n) ( 'GL.Text "i>=n" 'GL.:<>: 'GL.Text ": i="@@ -130,9 +130,25 @@ 'GL.:<>: 'GL.Text " n=" 'GL.:<>: 'GL.ShowType n )- , GN.KnownNat i+ , KnownNat i ) +-- | constraint for positive numbers+type LTEQC :: Nat -> Nat -> Constraint+class (KnownNat i, KnownNat n) => LTEQC i n where+instance+ ( KnownNat i+ , KnownNat n+ , FailUnless+ (i GL.<=? n)+ ( 'GL.Text "LTEQC n: requires n >= i but found i="+ 'GL.:<>: 'GL.ShowType i+ 'GL.:<>: 'GL.Text " n="+ 'GL.:<>: 'GL.ShowType n+ )+ ) =>+ LTEQC i n+ -- | constraint for DiffC with better error messages type DiffTC :: Nat -> Nat -> Nat -> Constraint type DiffTC i j n = (i <=! j, j <=! n)@@ -155,7 +171,7 @@ -- | product of a type level list as a 'Nat' type ProductT :: [Nat] -> Nat type family ProductT ns where- ProductT '[] = GL.TypeError ('GL.Text "ProductT: empty indices")+ ProductT '[] = GL.TypeError ( 'GL.Text "ProductT: empty indices") ProductT '[n] = n ProductT (n ': n1 ': ns) = n GN.* ProductT (n1 ': ns) @@ -193,7 +209,7 @@ [] -> programmError "ValidateNestedNonEmptyC: ('S 'Z): empty list of indices" instance ValidateNestedNonEmptyC x ( 'S zs) => ValidateNestedNonEmptyC (NonEmpty x) ( 'S ( 'S zs)) where validateNestedNonEmptyC ixes x@(n :| ns) xs =- let cs = map clOrdering $ compareLengths (x :| xs)+ let cs = map clOrdering $ compareLengths x xs in if all (Just EQ ==) cs then let zs = ns <> concatMap N.toList xs@@ -215,7 +231,7 @@ instance ValidateNestedListC x ( 'S n) => ValidateNestedListC [x] ( 'S ( 'S n)) where validateNestedListC ixes [] _ = Left $ "validateNestedListC: ixes=" ++ show ixes ++ ":no data!" validateNestedListC ixes x@(n : ns) xs =- let cs = map clOrdering $ compareLengths (x :| xs)+ let cs = map clOrdering $ compareLengths x xs in if all (Just EQ ==) cs then let zs = ns <> concat xs@@ -240,14 +256,14 @@ -- | convert a matrix index into nested lists type ListNST :: [Nat] -> Type -> Type type family ListNST ns a where- ListNST '[] _ = GL.TypeError ('GL.Text "ListNST: empty indices")+ ListNST '[] _ = GL.TypeError ( 'GL.Text "ListNST: empty indices") ListNST '[_] a = [a] ListNST (_ ': n1 ': ns) a = [ListNST (n1 ': ns) a] -- | convert a matrix index into nested lists type NonEmptyNST :: [Nat] -> Type -> Type type family NonEmptyNST ns a where- NonEmptyNST '[] _ = GL.TypeError ('GL.Text "NonEmptyNST: empty indices")+ NonEmptyNST '[] _ = GL.TypeError ( 'GL.Text "NonEmptyNST: empty indices") NonEmptyNST '[_] a = NonEmpty a NonEmptyNST (_ ': n1 ': ns) a = NonEmpty (NonEmptyNST (n1 ': ns) a) @@ -270,12 +286,12 @@ flattenNestedListC :: proxy a -> ListNST ns a -> Either String [a] -instance GL.TypeError ('GL.Text "NestedListC '[]: empty indices") => NestedListC '[] where+instance GL.TypeError ( 'GL.Text "NestedListC '[]: empty indices") => NestedListC '[] where nestedListToNonEmptyC = compileError "NestedListC '[]:nestedListToNonEmptyC" nestedNonEmptyToListC = compileError "NestedListC '[]:nestedNonEmptyToListC" flattenNestedListC = compileError "NestedListC '[]:flattenNestedListC" -instance PosT n => NestedListC '[n] where+instance PosC n => NestedListC '[n] where nestedListToNonEmptyC _ = \case [] -> Left "nestedListToNonEmptyC 'SZ no data" x : xs -> lmsg "nestedListToNonEmptyC 'SZ" $ lengthExact1 (fromNP @n) (x :| xs)@@ -284,7 +300,7 @@ [] -> Left "flattenNestedListC 'SZ no data" x : xs -> lmsg "flattenNestedListC 'SZ" $ lengthExact (fromN @n) (x : xs) -instance (PosT n, NestedListC (n1 ': ns)) => NestedListC (n ': n1 ': ns) where+instance (PosC n, NestedListC (n1 ': ns)) => NestedListC (n ': n1 ': ns) where nestedListToNonEmptyC p = \case [] -> Left "nestedListToNonEmptyC 'SS no data" x : xs -> do
test/TestFin.hs view
@@ -164,13 +164,13 @@ @?= Right (FinU @5 _4P _5P) , testCase "_Fin" $ mkFinC @5 _10P _5P- @?= Left "mkFin:10P is too large: maximum is 5P"+ @?= Left "mkFin:_10P is too large: maximum is _5P" , testCase "mkFinC" $ mkFinC @9 _4P _10P- @?= Left "mkFinC: 10P /= 9P at typelevel"+ @?= Left "mkFinC: _10P /= _9P at typelevel" , testCase "mkFinC" $ mkFinC @9 _12P _10P- @?= Left "mkFinC: 10P /= 9P at typelevel"+ @?= Left "mkFinC: _10P /= _9P at typelevel" , testCase "signum1" $ signum1 (Right (FinU @5 _4P _5P)) @?= Right (FinU @5 _1P _5P)@@ -229,7 +229,7 @@ , testCase "fin" $ fin @10 (-5) @?= Left "eitherPos: i<=0: found -5" , testCase "fin" $- fin @10 11 @?= Left "mkFin:11P is too large: maximum is 10P"+ fin @10 11 @?= Left "mkFin:_11P is too large: maximum is _10P" , testCase "fin" $ fin @10 10 @?= Right (FinU _10P _10P) , testCase "fin" $
test/TestFinMat.hs view
@@ -214,16 +214,16 @@ N.last xs @?= maxBound , testCase "showFinMat" $ map showFinMat [FinMatU @'[2, 3, 5] 0 (_2P :| [_3P, _5P]), toEnum 5 ..]- @?= ["0@{2,3,5}", "5@{2,3,5}", "10@{2,3,5}", "15@{2,3,5}", "20@{2,3,5}", "25@{2,3,5}"]+ @?= ["FinMat@0{2,3,5}", "FinMat@5{2,3,5}", "FinMat@10{2,3,5}", "FinMat@15{2,3,5}", "FinMat@20{2,3,5}", "FinMat@25{2,3,5}"] , testCase "nonEmptyToFinMat'" $ nonEmptyToFinMat' (_1P :| [_4P, _3P]) (_1P :| [_3P, _4P])- @?= Left "nonEmptyToFinMat:These es=outofbounds (4P,3P) as=(1P,1P) :| [(3P,4P)]"+ @?= Left "nonEmptyToFinMat:These es=outofbounds (_4P,_3P) as=(_1P,_1P) :| [(_3P,_4P)]" , testCase "nonEmptyToFinMat'" $ nonEmptyToFinMat' (_1P :| [_2P, _3P, _6P]) (_1P :| [_3P, _4P])- @?= Left "nonEmptyToFinMat:too many indices: expected 3 is=1P :| [2P,3P,6P] ns=1P :| [3P,4P]"+ @?= Left "nonEmptyToFinMat:too many indices: expected 3 is=_1P :| [_2P,_3P,_6P] ns=_1P :| [_3P,_4P]" , testCase "nonEmptyToFinMat'" $ nonEmptyToFinMat' (_1P :| [_2P]) (_1P :| [_3P, _4P])- @?= Left "nonEmptyToFinMat:not enough indices: expected 3 is=1P :| [2P] ns=1P :| [3P,4P]"+ @?= Left "nonEmptyToFinMat:not enough indices: expected 3 is=_1P :| [_2P] ns=_1P :| [_3P,_4P]" , testCase "nonEmptyToFinMat'" $ nonEmptyToFinMat' (_3P :| [_1P, _4P]) (_3P :| [_8P, _7P]) @?= Right (FinMatU @'[3, 8, 7] 115 (_3P :| [_8P, _7P]))@@ -370,45 +370,45 @@ , testCase "relPos" $ relPos ((_4P, _7P) :| [(_3P, _5P), (_2P, _5P)]) @?= (_P @175, 86) , testCase "readFinMat" $- readFinMat @'[7, 3, 3] "5@{7,3,3}xyz" @?= [(finMatC @'[1, 2, 3] @'[7, 3, 3], "xyz")]+ readFinMat @'[7, 3, 3] "FinMat@5{7,3,3}xyz" @?= [(finMatC @'[1, 2, 3] @'[7, 3, 3], "xyz")] , testCase "readFinMat" $ let m = finMatC @'[1, 2, 3] @'[7, 3, 3] in readFinMat @'[7, 3, 3] (show m ++ " ") @?= [(m, " ")] , testCase "readFinMat" $- readFinMat @'[7, 3, 3] "6@{1,2,3}xyz" @?= []+ readFinMat @'[7, 3, 3] "FinMat@6{1,2,3}xyz" @?= [] , testCase "readFinMat" $- readFinMat @'[1, 2, 3] " 4@{ 1, 2, 3}xy"+ readFinMat @'[1, 2, 3] " FinMat@4{ 1, 2, 3}xy" @?= [(FinMatU @'[1, 2, 3] 4 (_1P :| [_2P, _3P]), "xy")] , testCase "showFinMat'" $ showFinMat' (finMatC @'[2, 3, 5] @'[4, 4, 6])- @?= "40@{2,3,5|4,4,6}"+ @?= "FinMat@40{2,3,5|4,4,6}" , testCase "showFinMat'" $ showFinMat' (finMatC @'[1] @'[1])- @?= "0@{1|1}"+ @?= "FinMat@0{1|1}" , testCase "showFinMat'" $ showFinMat' (finMatC @(NN 123) @(NN 234))- @?= "6@{1,2,3|2,3,4}"+ @?= "FinMat@6{1,2,3|2,3,4}" , testCase "showFinMat'" $ showFinMat' (finMatC @(NN 111) @(NN 234))- @?= "0@{1,1,1|2,3,4}"+ @?= "FinMat@0{1,1,1|2,3,4}" , testCase "showFinMat'" $ showFinMat' (finMatC @(NN 114) @(NN 234))- @?= "3@{1,1,4|2,3,4}"+ @?= "FinMat@3{1,1,4|2,3,4}" , testCase "showFinMat'" $ showFinMat' (finMatC @(NN 9) @(NN 9))- @?= "8@{9|9}"+ @?= "FinMat@8{9|9}" , testCase "showFinMat" $ showFinMat (finMatC @'[1] @'[1])- @?= "0@{1}"+ @?= "FinMat@0{1}" , testCase "showFinMat" $ showFinMat (finMatC @'[1] @'[10])- @?= "0@{10}"+ @?= "FinMat@0{10}" , testCase "showFinMat" $ showFinMat (finMatC @'[10] @'[10])- @?= "9@{10}"+ @?= "FinMat@9{10}" , testCase "showFinMat" $ showFinMat (finMatC @'[4] @'[10])- @?= "3@{10}"+ @?= "FinMat@3{10}" , testCase "fromInteger1" $ fromInteger1 (minBound @(FinMat '[2, 3, 4])) 0 @?= Right (FinMatU @'[2, 3, 4] 0 (_2P :| [_3P, _4P]))@@ -434,20 +434,29 @@ toInteger1 (FinMatU @'[2, 3, 4] 12 (_2P :| [_3P, _4P])) @?= 12 , testCase "index lenses" $- finMatC @'[2,5,3,7] @'[2,12,13,8] ^. _i1- @?= FinU @2 _2P _2P+ finMatC @'[2, 5, 3, 7] @'[2, 12, 13, 8] ^. _i1+ @?= FinU @2 _2P _2P , testCase "index lenses" $- finMatC @'[2,5,3,7] @'[2,12,13,8] ^. _i2- @?= FinU @12 _5P _12P+ finMatC @'[2, 5, 3, 7] @'[2, 12, 13, 8] ^. _i2+ @?= FinU @12 _5P _12P , testCase "index lenses" $- finMatC @'[2,5,3,7] @'[2,12,13,8] ^. _i4- @?= FinU @8 _7P _8P+ finMatC @'[2, 5, 3, 7] @'[2, 12, 13, 8] ^. _i4+ @?= FinU @8 _7P _8P , testCase "finMat finMatC" $- finMat @'[2,12,13,8] (6 + 2*8 + 4*13*8 + 1*12*13*8)- @?= Right (finMatC @'[2,5,3,7] @'[2,12,13,8])+ finMat @'[2, 12, 13, 8] (6 + 2 * 8 + 4 * 13 * 8 + 1 * 12 * 13 * 8)+ @?= Right (finMatC @'[2, 5, 3, 7] @'[2, 12, 13, 8]) , testCase "finMat finMatC" $- finMat @'[21] 0- @?= Right (finMatC @'[1] @'[21])+ finMat @'[21] 0+ @?= Right (finMatC @'[1] @'[21])+ , testCase "_finMatCons" $+ (finMatC @'[2,1] @'[7,1] ^. _finMatCons) @?= (finC @2 @7, finMatC @'[1] @'[1])+ , testCase "_finMatCons" $+ (finMatC @'[2,1] @'[7,4] ^. _finMatCons) @?= (finC @2 @7, finMatC @'[1] @'[4])+ , testCase "_finMatCons" $+ (finMatC @'[2,2] @'[7,2] ^. _finMatCons) @?= (finC @2 @7, finMatC @'[2] @'[2])++ , testCase "_finMatCons" $+ (finMatC @'[2,4] @'[7,4] ^. _finMatCons) @?= (finC @2 @7, finMatC @'[4] @'[4]) ] fmi237' :: NonEmpty (FinMat '[2, 3, 7])@@ -461,3 +470,4 @@ fmiNS :: NonEmpty Int -> NonEmpty (NonEmpty Int) fmiNS = traverse (N.fromList . enumFromTo 1)+
test/TestMat.hs view
@@ -1,5 +1,8 @@ {-# OPTIONS -Wno-orphans #-} {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE OverloadedStrings #-}@@ -7,6 +10,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-} module TestMat where @@ -40,6 +44,9 @@ import Test.Tasty import Test.Tasty.HUnit import qualified Test.Tasty.QuickCheck as TQ+import Unsafe.Coerce+import qualified GHC.TypeNats as GN+import Data.Proxy instance (NS ns, Arbitrary a) => Arbitrary (Mat ns a) where arbitrary = sequenceA $ mat @ns (repeat arbitrary)@@ -126,16 +133,16 @@ matToNestedListC (fmap (show . succ) m35) @?= [["2", "3", "4", "5", "6"], ["7", "8", "9", "10", "11"], ["12", "13", "14", "15", "16"]] , testCase "totuple" $- toTupleC (mat' @'[2, 3, 2] [1 :: Int .. 12])+ toTupleC (mat' @'[2, 3, 2] @Int [1 .. 12]) @?= (((1, 2), (3, 4), (5, 6)), ((7, 8), (9, 10), (11, 12))) , testCase "fromtuple" $ fromTupleC (((1, 2), (3, 4), (5, 6)), ((7, 8), (9, 10), (11, 12)))- @?= mat' @'[2, 3, 2] [1 :: Int .. 12]+ @?= mat' @'[2, 3, 2] @Int [1 .. 12] , testCase "change row" $- (mat' @'[3, 4] [1 :: Int .. 12] & ixSlice @'[2, 3] .~ 999)+ (mat' @'[3, 4] @Int [1 .. 12] & ixSlice @'[2, 3] .~ 999) @?= mat' @'[3, 4] [1, 2, 3, 4, 5, 6, 999, 8, 9, 10, 11, 12] , testCase "change row" $- (mat' @'[3, 4] [1 :: Int .. 12] & ixSlice @'[1] *~ 999)+ (mat' @'[3, 4] @Int [1 .. 12] & ixSlice @'[1] *~ 999) @?= mat' @'[3, 4] [999, 1998, 2997, 3996, 5, 6, 7, 8, 9, 10, 11, 12] , testCase "change row" $ m345 ^. ixSlice @'[2, 3]@@ -144,16 +151,16 @@ (m35 & ixSlice @'[2] . traverse *~ 100) @?= mat' @'[3, 5] [1, 2, 3, 4, 5, 600, 700, 800, 900, 1000, 11, 12, 13, 14, 15] , testCase "change row" $- (mat' @'[2, 1, 2, 3, 4] [1 :: Int .. 48] & ixSlice @'[2, 1, 1] . traverse *~ 100)+ (mat' @'[2, 1, 2, 3, 4] @Int [1 .. 48] & ixSlice @'[2, 1, 1] . traverse *~ 100) @?= mat' @'[2, 1, 2, 3, 4] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48] , testCase "change row" $ m345 ^. ixSlice @'[2] @?= mat' @'[4, 5] ['U' .. 'h'] , testCase "not as useful: nests all stuff" $- fmap sum (matToNestedVecC @'[2, 3] (mat' [1 :: Int .. 6]))+ fmap sum (matToNestedVecC @'[2, 3] (mat' @_ @Int [1 .. 6])) @?= 6 .| 15 , testCase "mapLeaf: change the lowest rows into lists" $- mapLeaf (const sum) (mat' @'[4, 3] [1 :: Int .. 12])+ mapLeaf (const sum) (mat' @'[4, 3] @Int [1 .. 12]) @?= mat' @'[4] [6, 15, 24, 33] , testCase "mapLeafSimple" $ mapLeafSimple (fmap . (,) . fmPos) (gen' @(NN 43) id)@@ -174,19 +181,19 @@ foldMapLeafR (\i m -> [(fmPos i, sum m, toList m)]) (mm @(NN 234)) @?= [(20, 90, [21, 22, 23, 24]), (16, 74, [17, 18, 19, 20]), (12, 58, [13, 14, 15, 16]), (8, 42, [9, 10, 11, 12]), (4, 26, [5, 6, 7, 8]), (0, 10, [1, 2, 3, 4])] , testCase "addition" $- mat' @'[2, 3] [1 .. 6] + mat' [100 :: Int .. 105]+ mat' @'[2, 3] @Int [1 .. 6] + mat' [100 .. 105] @?= mat' [101, 103, 105, 107, 109, 111] , testCase "multiplication" $- mat' @'[2, 3] [1 .. 6] * mat' [100 :: Int .. 105]+ mat' @'[2, 3] @Int [1 .. 6] * mat' [100 .. 105] @?= mat' [100, 202, 306, 412, 520, 630] -- note: have to use mat' for inference to work , testCase "transpose" $- transposeMat (mat' @'[2, 3] [1 :: Int .. 6])+ transposeMat (mat' @'[2, 3] @Int [1 .. 6]) @?= mat' [1, 4, 2, 5, 3, 6] , testCase "transpose iso" $ transposeMat (transposeMat m345) @?= m345 , testCase "diagonal" $- diagonal (mat' @'[3, 3, 4] [1 :: Int .. 36])+ diagonal (mat' @'[3, 3, 4] @Int [1 .. 36]) @?= mat' [1, 2, 3, 4, 17, 18, 19, 20, 33, 34, 35, 36] , testCase "diagonal" $ diagonal (gen @'[4, 4] succ)@@ -201,31 +208,31 @@ finMatMatrix @'[2, 3, 1] @?= mat' (toList (N.map (fr . (nonEmptyToFinMat <=< toPositives)) ([1, 1, 1] :| [[1, 2, 1], [1, 3, 1], [2, 1, 1], [2, 2, 1], [2, 3, 1]]))) , testCase "insert row" $- insertRow @2 (mat' @'[3, 4] [100 .. 111]) (mat' @'[2, 3, 4] [1 :: Int .. 24])+ insertRow @2 (mat' @'[3, 4] [100 .. 111]) (mat' @'[2, 3, 4] @Int [1 .. 24]) @?= mat' [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] , testCase "insert column" $- insertCol @2 (mat' @'[2, 4] [100 .. 107]) (mat' @'[2, 3, 4] [1 :: Int .. 24])+ insertCol @2 (mat' @'[2, 4] [100 .. 107]) (mat' @'[2, 3, 4] @Int [1 .. 24]) @?= mat' [1, 2, 3, 4, 100, 101, 102, 103, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 104, 105, 106, 107, 17, 18, 19, 20, 21, 22, 23, 24] , testCase "delete row" $- deleteRow @2 (mat' @'[2, 3, 4] [1 :: Int .. 24])+ deleteRow @2 (mat' @'[2, 3, 4] @Int [1 .. 24]) @?= mat' [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] , testCase "insert/delete row" $ deleteRow @2 (insertRow @2 (mat' @'[4, 5] [100 .. 119]) m345') @?= m345' , testCase "to nested lists" $- matToNestedListC (mat' @'[2, 3, 4] [1 :: Int .. 24])+ matToNestedListC (mat' @'[2, 3, 4] @Int [1 .. 24]) @?= [[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]] , testCase "concat vertically" $- matToNestedListC (appendV (mat' @'[2, 3, 2] [1 .. 12]) (mat' @'[5, 3, 2] [100 :: Int .. 129]))+ matToNestedListC (appendV (mat' @'[2, 3, 2] [1 .. 12]) (mat' @'[5, 3, 2] @Int [100 .. 129])) @?= [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]], [[100, 101], [102, 103], [104, 105]], [[106, 107], [108, 109], [110, 111]], [[112, 113], [114, 115], [116, 117]], [[118, 119], [120, 121], [122, 123]], [[124, 125], [126, 127], [128, 129]]] , testCase "concat vertically" $- matToNestedListC (appendV (mat' @'[2, 3] [1 .. 6]) (mat' @'[7, 3] [100 :: Int .. 120]))+ matToNestedListC (appendV (mat' @'[2, 3] [1 .. 6]) (mat' @'[7, 3] @Int [100 .. 120])) @?= [[1, 2, 3], [4, 5, 6], [100, 101, 102], [103, 104, 105], [106, 107, 108], [109, 110, 111], [112, 113, 114], [115, 116, 117], [118, 119, 120]] , testCase "concat horizontally" $- matToNestedListC (appendH (mat' @'[5, 2, 2] [1 .. 20]) (mat' @'[5, 3, 2] [100 :: Int .. 129]))+ matToNestedListC (appendH (mat' @'[5, 2, 2] [1 .. 20]) (mat' @'[5, 3, 2] @Int [100 .. 129])) @?= [[[1, 2], [3, 4], [100, 101], [102, 103], [104, 105]], [[5, 6], [7, 8], [106, 107], [108, 109], [110, 111]], [[9, 10], [11, 12], [112, 113], [114, 115], [116, 117]], [[13, 14], [15, 16], [118, 119], [120, 121], [122, 123]], [[17, 18], [19, 20], [124, 125], [126, 127], [128, 129]]] , testCase "concat horizontally" $- matToNestedListC (appendH (mat' @'[3, 2] [1 .. 6]) (mat' @'[3, 7] [100 :: Int .. 120]))+ matToNestedListC (appendH (mat' @'[3, 2] @Int [1 .. 6]) (mat' @'[3, 7] @Int [100 .. 120])) @?= [[1, 2, 100, 101, 102, 103, 104, 105, 106], [3, 4, 107, 108, 109, 110, 111, 112, 113], [5, 6, 114, 115, 116, 117, 118, 119, 120]] , testCase "consMat" $ (gen @'[3, 4] succ ^. consMat)@@ -282,20 +289,20 @@ nestedVecToMatC (matToNestedVecC m345) @?= m345 -- works without @'[3,4,5] cos @?= tells us the type , testCase "delete item from 1d mat'" $- deleteRow @4 (mat' @'[10] [1 :: Int .. 10])+ deleteRow @4 (mat' @'[10] @Int [1 .. 10]) @?= mat' [1, 2, 3, 5, 6, 7, 8, 9, 10] , testCase "redim" $- redim (mat' @'[2, 3, 5] [1 :: Int .. 30])- @?= mat' @'[6, 5] [1 :: Int .. 30]+ redim (mat' @'[2, 3, 5] @Int [1 .. 30])+ @?= mat' @'[6, 5] @Int [1 .. 30] , testCase "redim" $- redim (mat' @'[5, 9, 4] [1 :: Int .. 180])- @?= mat' @'[3, 6, 10] [1 :: Int .. 180]+ redim (mat' @'[5, 9, 4] @Int [1 .. 180])+ @?= mat' @'[3, 6, 10] @Int [1 .. 180] , testCase "redim" $- redim (mat' @'[18] [1 :: Int .. 18])- @?= mat' @'[3, 2, 3] [1 :: Int .. 18]+ redim (mat' @'[18] @Int [1 .. 18])+ @?= mat' @'[3, 2, 3] @Int [1 .. 18] , testCase "redim" $- redim (mat' @'[3, 2, 3] [1 :: Int .. 18])- @?= mat' @'[18] [1 :: Int .. 18]+ redim (mat' @'[3, 2, 3] @Int [1 .. 18])+ @?= mat' @'[18] @Int [1 .. 18] , testCase "diagonal" $ diagonal (gen @'[4, 4] succ) @?= mat' @'[4] [1, 6, 11, 16]@@ -306,7 +313,7 @@ diagonal (mm @(NN 99)) @?= mat' @'[9] [1, 11, 21, 31, 41, 51, 61, 71, 81] , testCase "multMat" $- multMat (mat' @'[2, 5] [1 :: Int .. 10]) (mat' @'[5, 6] [1 :: Int .. 30])+ multMat (mat' @'[2, 5] @Int [1 .. 10]) (mat' @'[5, 6] @Int [1 .. 30]) @?= mat' @'[2, 6] [255, 270, 285, 300, 315, 330, 580, 620, 660, 700, 740, 780] , testCase "universe1 enum" $ toNonEmpty (finMatMatrix @'[2, 3, 7])@@ -315,16 +322,16 @@ toList (finMatMatrix @'[2, 3, 7]) @?= toList fmi237' , testCase "D3" $- mat' @(D3 2 3 4) [1 :: Int .. 24]+ mat' @(D3 2 3 4) @Int [1 .. 24] @?= mat' @'[2, 3, 4] [1 .. 24] , testCase "ixMat" $- (mat' @'[2, 3, 4] [1 :: Int .. 24] & ixMat (finMatC @'[2, 3, 1]) +~ 100)+ (mat' @'[2, 3, 4] @Int [1 .. 24] & ixMat (finMatC @'[2, 3, 1]) +~ 100) @?= mat' @'[2, 3, 4] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 121, 22, 23, 24] , testCase "ixMat" $- (mat' @'[2, 3, 4] [1 :: Int .. 24] & ixMat (finMatC @'[2, 3, 4]) +~ 100)+ (mat' @'[2, 3, 4] @Int [1 .. 24] & ixMat (finMatC @'[2, 3, 4]) +~ 100) @?= mat' @'[2, 3, 4] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 124] , testCase "read" $- (read @(Mat (D1 4) Int) $ show $ mat' @'[4] [1 :: Int .. 4])+ (read @(Mat (D1 4) Int) $ show $ mat' @'[4] @Int [1 .. 4]) @?= (1 .: 2 .: 3 .| 4) , testCase "read" $ let m = gen' @'[1] id@@ -345,10 +352,10 @@ let m = ('x', True, ['a' .. 'z'], gen' @'[1, 2, 3] id, False) in read (show m) @?= m , testCase "read" $- let m = mat' @'[4, 5] [1 :: Int .. 20]+ let m = mat' @'[4, 5] @Int [1 .. 20] in read @(Mat (D2 4 5) Int) (show m) @?= m , testCase "read" $- let m = mat' @'[1, 2, 3, 4] [1 :: Int .. 24]+ let m = mat' @'[1, 2, 3, 4] @Int [1 .. 24] in read (show m) @?= m , testCase "read" $ let m = toND @1 (mm @(NN 2352))@@ -361,15 +368,15 @@ in read (show m) @?= m , testCase "sortByRows" $ sortByRows (flip compare) (mat' @'[4, 2] [10, 9, 1, 2, 100, 200, 300, 400])- @?= mat' [10, 9, 2, 1, 200, 100, 400, 300 :: Int]+ @?= mat' @_ @Int [10, 9, 2, 1, 200, 100, 400, 300] , testCase "sortByT" $- sortByT (flip compare) (mat' @'[4] [10 :: Int, 9, 1, 2])+ sortByT (flip compare) (mat' @'[4] @Int [10, 9, 1, 2]) @?= (10 .: 9 .: 2 .| 1) , testCase "sortByT" $- sortByT compare (mat' @'[4] [10 :: Int, 9, 1, 2])+ sortByT compare (mat' @'[4] @Int [10, 9, 1, 2]) @?= (1 .: 2 .: 9 .| 10) , testCase "sortByRows" $- sortByRows compare (mat' @'[4, 2] [10 :: Int, 9, 1, 2, 100, 200, 300, 400])+ sortByRows compare (mat' @'[4, 2] @Int [10, 9, 1, 2, 100, 200, 300, 400]) @?= mat' [9, 10, 1, 2, 100, 200, 300, 400] , testCase "totuple" $ toTupleC (vec' "abc")@@ -381,7 +388,7 @@ fromTupleC (One 'a') @?= se1 'a' , testCase "fromtuple" $- fromTupleC (1, 2, 3 :: Int)+ fromTupleC @_ @Int (1, 2, 3) @?= 1 .: 2 .| 3 , testCase "consMat" $ (mat' @'[1] "x" ^. consMat)@@ -426,19 +433,19 @@ (mat' @'[5, 3] ['A' .. 'O'] ^. snocMat) @?= (mat' @'[4, 3] ['A' .. 'L'], mat' @'[3] "MNO") , testCase "field lens" $- (mat' @'[3, 3, 4] [1 :: Int .. 36] ^. _r3 . _r1)+ (mat' @'[3, 3, 4] @Int [1 .. 36] ^. _r3 . _r1) @?= vec' @4 [25, 26, 27, 28] , testCase "field lens" $- (mat' @'[3, 3, 4] [1 :: Int .. 36] ^. _r3 . _r1)+ (mat' @'[3, 3, 4] @Int [1 .. 36] ^. _r3 . _r1) @?= vec' @4 [25, 26, 27, 28] , testCase "field lens update" $ (mat' @'[2, 1, 4] ['A' .. 'H'] & _r2 . _r1 . _r3 %~ toLower) @?= mat' "ABCDEFgH" , testCase "field lens" $- (mat' @'[7] [1 :: Int .. 7] ^. _r3)+ (mat' @'[7] @Int [1 .. 7] ^. _r3) @?= 3 , testCase "field lens" $- (mat' @'[7, 4] [1 :: Int .. 28] ^. _r3 . _r2)+ (mat' @'[7, 4] @Int [1 .. 28] ^. _r3 . _r2) @?= 10 , testCase "subsetRows" $ subsetRows @2 @2 (gen @'[2, 5] succ)@@ -674,13 +681,13 @@ (('x', Eof1) ^. from (consMat @'[1])) @?= se1 'x' , testCase "nestedListToMatC" $- nestedListToMatC @'[2, 3, 5] [[[1 :: Int, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30]]]+ nestedListToMatC @'[2, 3, 5] @Int [[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30]]] @?= Right (mat' @'[2, 3, 5] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]) , testCase "nestedListToMatC" $- nestedListToMatC @'[3, 3, 5] [[[1 :: Int, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30]]]+ nestedListToMatC @'[3, 3, 5] @Int [[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30]]] @?= Left "LT: not enough elements: expected 3 found 2" , testCase "nestedListToMatC" $- nestedListToMatC @'[2, 3, 6] [[[1 :: Int, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30]]]+ nestedListToMatC @'[2, 3, 6] @Int [[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], [[16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30]]] @?= Left "not enough elements: expected 6 found 5" , testCase "indexRow" $ indexRow (fr $ fin @7 1) (gen' @(NN 73) id)@@ -692,19 +699,19 @@ indexRow (fr $ fin @7 7) (gen' @(NN 73) id) @?= vec' [[7, 1], [7, 2], [7, 3]] , testCase "readVec" $- readVec @5 @Int (show (mm @(NN 5))) @?= [(vec' [1 .. 5], "")]+ readVec @5 @Int (show (vec' @5 [1::Int ..5])) @?= [(vec' [1 .. 5], "")] , testCase "readMat2" $ let m = mat' @'[3, 7] ['a' .. 'u'] in readMat2 @3 @7 @Char (show m ++ "xyz") @?= [(m, "xyz")] , testCase "readVec" $ let m = mat' @'[7] ['a' .. 'g'] in readVec @7 @Char (show m ++ " xyz") @?= [(m, " xyz")]- , testCase "readMat2" $- let m = mm @(NN 372)- in readMat @(NN 372) @Int (show m ++ "xyz") @?= [(m, "xyz")] -- dont need type application but here we have inference+ , testCase "readMat" $+ let m = mat' @'[3,7,2] [1::Int .. 42]+ in readMat @'[3,7,2] @Int (show m ++ "xyz") @?= [(m, "xyz")] -- dont need type application but here we have inference , testCase "readMat12" $- let m = toVec (mm @(NN 372))- in readVec @3 @(Mat2 7 2 Int) (show m ++ "xyz") @?= [(m, "xyz")] -- dont need type application but here we have inference+ let m = mat' @'[3,7,2] [1::Int .. 42]+ in readMat @'[3,7,2] @Int (show m ++ "xyz") @?= [(m, "xyz")] -- dont need type application but here we have inference , testCase "readMat3456" $ let m = toMat2 (mm @(NN 3456)) in readMat2 @3 @4 @(Mat2 5 6 Int) (show m ++ "xyz") @?= [(m, "xyz")] -- dont need type application but here we have inference@@ -722,19 +729,19 @@ @?= vec' @1 [99] , testCase "(.:)" $ (12 .: 44 .| 99)- @?= vec' @3 [12 :: Int, 44, 99]+ @?= vec' @3 @Int [12, 44, 99] , testCase "(.:)" $ (5 .| 10 .:: 15 .| 20 .|| (25 .| 30))- @?= mat2' @3 @2 [5 :: Int, 10, 15, 20, 25, 30]+ @?= mat2' @3 @2 @Int [5, 10, 15, 20, 25, 30] , testCase "(.:)" $ se2 (5 .| 10 .:: 15 .| 20 .|| (25 .| 30))- @?= mat' @'[1, 3, 2] [5 :: Int, 10, 15, 20, 25, 30]+ @?= mat' @'[1, 3, 2] @Int [5, 10, 15, 20, 25, 30] , testCase "nestedListToMatValidated" $ let x = [[[[1 :: Int, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27]]]]- in nestedListToMatValidated @(NN 1234) x @?= Left "validateNestedListC: lengths=[4,4,4,4,4,7] ixes=[1P,2P,3P]"+ in nestedListToMatValidated @(NN 1234) x @?= Left "validateNestedListC: lengths=[4,4,4,4,4,7] ixes=[_1P,_2P,_3P]" , testCase "nestedListToMatValidated" $ let x = [[[[1 :: Int, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], []]]]- in nestedListToMatValidated @(NN 1234) x @?= Left "validateNestedListC: lengths=[4,4,4,4,4,0] ixes=[1P,2P,3P]"+ in nestedListToMatValidated @(NN 1234) x @?= Left "validateNestedListC: lengths=[4,4,4,4,4,0] ixes=[_1P,_2P,_3P]" , testCase "nestedListToMatValidated" $ let x = [[[[1 :: Int, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]] in nestedListToMatValidated @(NN 1234) x @?= Right (mat' @'[1, 2, 3, 4] [1 .. 24])@@ -812,7 +819,7 @@ unfoldrRep @(Vec 5) (\i s -> (drop 1 s, (fmPos i, head s))) ['a' .. 'h'] @?= ("fgh", vec' @5 [(0, 'e'), (1, 'd'), (2, 'c'), (3, 'b'), (4, 'a')]) , testCase "fillTraversable" $- fillTraversable @(MatN 234) (pure ()) [1 :: Int .. 40]+ fillTraversable @(MatN 234) @Int (pure ()) [1.. 40] @?= Right ([25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40], mat' @'[2, 3, 4] [1 .. 24]) , testCase "toInteger1" $ toInteger1 (pure @(Mat2 4 2) EQ)@@ -895,14 +902,98 @@ , testCase "fromInteger1" $ fromInteger1 (minBound @(Mat '[2, 5] Int8)) (-1276136419117121619201) @?= Left "cap=(-1276136419117121619200,1180591620717411303423):padL: negative fill: would need to truncate the data"- , testCase "lenses mixed" $- mm @(NN 1234) ^. _r1 . _r1 . _c2 . snocMat . _1 . consMat- @?= (2,vec @1 [6])-+ mm @(NN 1234) ^. _r1 . _r1 . _c2 . snocMat . _1 . consMat+ @?= (2, vec @1 [6]) , testCase "lenses mixed" $ mm @(NN 734) ^. _c3 . snocMat . _1 . _c4 . _r5- @?= 60+ @?= 60+ , testCase "withN" $+ let s = withN 5 $ \(_ :: x n) ->+ withN 3 $ \(_ :: x m) ->+ withN 2 $ \(_ :: x p) ->+ let w1 :: Mat2 n m Int -- if you use let statements then must have signatures else fails with constraints not satisfied+ w1 = mat2 @n @m [1 ..]+ w2 :: Mat2 m p Int+ w2 = mat2 @m @p [10 ..]+ z = multMat w1 w2+ in show (fromNSP @'[n, m, p], z)+ in read @(NonEmpty Pos, Mat2 5 2 Int) s+ @?= (_5P :| [_3P, _2P], mat2 @5 @2 [76, 82, 184, 199, 292, 316, 400, 433, 508, 550])+ , testCase "withN" $+ let s = withN 5 $ \(_ :: x n) ->+ withN 3 $ \(_ :: x m) ->+ show (mat2 @n @m @Int [1 ..] `multMat` mat2 @m @n @Int [10 ..])+ in read @(Mat2 5 5 Int) s @?= mat2' @5 @5 [100, 106, 112, 118, 124, 235, 250, 265, 280, 295, 370, 394, 418, 442, 466, 505, 538, 571, 604, 637, 640, 682, 724, 766, 808]+ , testCase "withN" $+ let s = withN 5 $ \(_ :: x n) -> show (vec @n @Int [1 ..])+ in read @(Vec 5 Int) s @?= vec' @5 [1 .. 5]+ , testCase "withN" $+ let s = withN 5 $ \(_ :: x n) ->+ withN 7 $ \(_ :: x m) -> show (mat2 @n @m @Int [1 ..], mat2 @m @n ['a' ..])+ in read @(Mat2 5 7 Int, Mat2 7 5 Char) s @?= (mat2' @5 @7 [1 .. 35], mat2 @7 @5 ['a' ..])+ , testCase "withN2" $+ let z = withN2 4 5 $ \(_ :: p n) (_ :: p m) -> show (mat2 @n @m ['a' ..])+ in read @(Mat2 4 5 Char) z @?= mat2' @4 @5 ['a' .. 't']+ , testCase "withN3" $+ withN3 2 3 4 (\(_ :: z n) (_ :: z m) (_ :: z q) -> fromNSP @'[n, m, q])+ @?= _2P :| [_3P, _4P]+ , testCase "withN3" $+ let z = withN 4 $ \(_ :: p n) -> show (mat2 @2 @n @Int [1..] ^. _row @1)+ in read @(Vec 4 Int) z @?= vec' @4 [1 .. 4]+ , testCase "withN3" $+ let z = withN 4 $ \(_ :: p n) -> show (mat2 @2 @n @Int [1 ..] ^. _row @2)+ in read @(Vec 4 Int) z @?= vec' @4 [5 .. 8]++ , testCase "withNMin3" $+ let z = withNMin3 5 (\(_ :: p n) -> withNMin3 4 (\(_ :: p m) -> show (mat2 @n @m [1::Int ..] ^. _c2)))+ in read @(Vec 5 Int) z @?= vec' @5 [2,6,10,14,18]++ , testCase "rotateLeft rotateRight" $+ let z = mm @(NN 57)+ in rotateLeft (rotateRight z) @?= z+ , testCase "rotateLeft" $+ rotateLeft (mm @(NN 35))+ @?= mat2' @5 @3 [5,10,15,4,9,14,3,8,13,2,7,12,1,6,11]+ ,testCase "rotateRight" $+ rotateRight (mm @(NN 35))+ @?= mat2' @5 @3 [11,6,1,12,7,2,13,8,3,14,9,4,15,10,5]+ , testCase "rotateRight transpose rotateRight" $+ let z = mm @(NN 57)+ in (transposeMat . rotateLeft . transposeMat) z @?= rotateRight z++ , testCase "determinant" $+ determinant (mat2' @3 @3 @Int [2, -3, 1, 2, 0, -1, 1, 4, 5])+ @?= 49+ , testCase "determinant" $+ determinant (mat2' @3 @3 @Int [1, 3, 2, -3, -1, -3, 2, 3, 1])+ @?= (-15)+ , testCase "determinant" $+ determinant (mat2' @4 @4 @Int [3, 2, 0, 1, 4, 0, 1, 2, 3, 0, 2, 1, 9, 2, 3, 1])+ @?= 24+ , testCase "determinant" $+ determinant (mat2' @4 @4 @Int [1, 0, 2, -1, 3, 0, 0, 5, 2, 1, 4, -3, 1, 0, 5, 0])+ @?= 30+ , testCase "determinant" $+ determinant (mat2' @4 @4 @Int [1, 0, 4, -6, 2, 5, 0, 3, -1, 2, 3, 5, 2, 1, -2, 3])+ @?= 318+ , testCase "determinant" $+ determinant (mat2' @2 @2 @Int [1, 2, 3, 4])+ @?= (-2)++ , testCase "determinant" $+ determinant (mat2' @1 @1 @Int [-5])+ @?= (-5)+ , testCase "deleteColumnL" $+ deleteColumnL _2P 1 [1,2::Int] @?= [1]+ , testCase "deleteColumnL" $+ deleteColumnL _2P 0 [1,2::Int] @?= [2]+ , testCase "deleteColumnL" $+ deleteColumnL _3P 1 [1::Int .. 12] @?= [1,3,4,6,7,9,10,12]+ , testCase "deleteColumnL" $+ deleteColumnL _2P 1 [1..10::Int] @?= [1,3,5,7,9]+ , testCase "deleteColumnL" $+ deleteColumnL _1P 0 [1::Int] @?= [] ] suiteCheckers :: TestTree@@ -920,3 +1011,55 @@ fmi237 :: NonEmpty (NonEmpty Int) fmi237 = fmap N.fromList ([1, 1, 1] :| [[1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 1, 5], [1, 1, 6], [1, 1, 7], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 2, 6], [1, 2, 7], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 3, 5], [1, 3, 6], [1, 3, 7], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 1, 5], [2, 1, 6], [2, 1, 7], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 2, 5], [2, 2, 6], [2, 2, 7], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 3, 5], [2, 3, 6], [2, 3, 7]])++-- ghc 9.2 needs explicit kinds for "i" and "n"+overrideDictPositive :: forall (i :: Nat) (n :: Nat) p . p n -> (i GN.<=? n) :~: 'True+overrideDictPositive _ = unsafeCoerce Refl++-- | lift a positive number to the typelevel+withN :: Int -> (forall n. FinC 1 n => Proxy n -> x) -> x+withN i f+ | i <= 1 = normalError $ "withN: index must be at least 1:found " ++ show i+ | otherwise =+ case GN.someNatVal (toEnum i) of+ GN.SomeNat (pn :: Proxy n) ->+ case overrideDictPositive @1 pn of+ Refl -> f (Proxy @n)++-- | lift a positive number to the typelevel+withNMin2 :: Int -> (forall n . (FinC 2 n, FinC 1 n) => Proxy n -> x) -> x+withNMin2 i f+ | i < 2 = normalError $ "withNMin2: index must be at least 2:found " ++ show i+ | otherwise =+ case GN.someNatVal (toEnum i) of+ GN.SomeNat (pn :: Proxy n) ->+ case overrideDictPositive @1 pn of+ Refl ->+ case overrideDictPositive @2 pn of+ Refl -> f (Proxy @n)++withNMin3 :: Int -> (forall n . (FinC 3 n, FinC 2 n, FinC 1 n) => Proxy n -> x) -> x+withNMin3 i f+ | i < 3 = normalError $ "withNMin3: index must be at least 3:found " ++ show i+ | otherwise =+ case GN.someNatVal (toEnum i) of+ GN.SomeNat (pn :: Proxy n) ->+ case overrideDictPositive @1 pn of+ Refl ->+ case overrideDictPositive @2 pn of+ Refl ->+ case overrideDictPositive @3 pn of+ Refl -> f (Proxy @n)++-- | lift two positive numbers to the typelevel+withN2 :: Int -> Int -> (forall n m. (FinC 1 n, FinC 1 m) => Proxy n -> Proxy m -> x) -> x+withN2 i j f = withN i $ \p1 -> withN j $ \p2 -> f p1 p2++-- | lift three positive numbers to the typelevel+withN3 :: Int -> Int -> Int -> (forall n m p. (FinC 1 n, FinC 1 m, FinC 1 p) => Proxy n -> Proxy m -> Proxy p -> x) -> x+withN3 i j k f = withN i $ \p1 -> withN j $ \p2 -> withN k $ \p3 -> f p1 p2 p3++-- | lift four positive numbers to the typelevel+withN4 :: Int -> Int -> Int -> Int -> (forall n m p q. (FinC 1 n, FinC 1 m, FinC 1 p, FinC 1 q) => Proxy n -> Proxy m -> Proxy p -> Proxy q -> x) -> x+withN4 i j k l f = withN i $ \p1 -> withN j $ \p2 -> withN k $ \p3 -> withN l $ \p4 -> f p1 p2 p3 p4+
test/TestNatHelper.hs view
@@ -43,5 +43,5 @@ validateNestedList ([] :: [()]) @?= Left "validateNestedListC: ixes=[]:no data!" , testCase "validateNestedList" $- validateNestedList [[1 :: Int, 2], [1, 2], [1, 2, 3]] @?= Left "validateNestedListC: lengths=[2,2,3] ixes=[3P]"+ validateNestedList [[1 :: Int, 2], [1, 2], [1, 2, 3]] @?= Left "validateNestedListC: lengths=[2,2,3] ixes=[_3P]" ]