summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwchresta <>2020-02-18 03:47:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2020-02-18 03:47:00 (GMT)
commit6c4cf614c9739c6e40572b60891f91c39a9db501 (patch)
treef0264edb5bb985f2177ea03215bcef52d4da55a8
parent154c73c00d693c82b4f7233bdddca2f6ae6dcf8c (diff)
version 0.3HEAD0.3master
-rw-r--r--ChangeLog.md3
-rw-r--r--README.md3
-rw-r--r--matrix-static.cabal8
-rw-r--r--src/Data/Matrix/Static.hs18
-rw-r--r--test/Spec.hs33
5 files changed, 53 insertions, 12 deletions
diff --git a/ChangeLog.md b/ChangeLog.md
index 1c81ce9..8546a03 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,6 @@
+# Version 0.3 - 17.02.2020
+* Fix Applicative and Monoid instances (thanks @davidsd)
+
# Version 0.2 - 16.10.2018
* Fix bug with the types of splitBlocks (Incompatible change)
diff --git a/README.md b/README.md
index d70a233..fe5b3fb 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,12 @@
[![Hackage](https://img.shields.io/hackage/v/matrix-static.svg)](https://hackage.haskell.org/package/matrix-static)
[![Hackage Deps](https://img.shields.io/hackage-deps/v/matrix-static.svg)](http://packdeps.haskellers.com/reverse/matrix-static)
-
# matrix-static
A static wrapper around the [matrix](https://hackage.haskell.org/package/matrix) library. It provides a data type `Matrix m n a` derived from `matrix`'s `Matrix a` with additional information about the matix dimension `m n` as type-level Nat's.
+An alternative to this library is [static-tensor](https://hackage.haskell.org/package/static-tensor-0.2.1.0/docs/Data-Matrix-Static.html) that might better fit your needs. Choose `matrix-static` if you are familiar with `matrix` and want more guarantees at compile time. Choose `static-tensor` for most other use cases.
+
(Almost) all functions provided by `Data.Matrix` are wrapped. These wrappers guarantee during compile time that the matrix dimension are correct. As such, runtime errors due to mismatching matrix dimensions are minimized. Also, some performance improvements are achieved by not having to do dimension checks during runtime.
Some functions take indices `i` as parameters (e.g. `Matrix.Data.mapCol`).
diff --git a/matrix-static.cabal b/matrix-static.cabal
index 187369a..1e0afa3 100644
--- a/matrix-static.cabal
+++ b/matrix-static.cabal
@@ -4,10 +4,10 @@ cabal-version: 1.12
--
-- see: https://github.com/sol/hpack
--
--- hash: 8683931cd52dfb6652bbc41d626105dfbfa75efa4e930a75fd01df7c6301f49e
+-- hash: 8bf6109534a0cb0620204ae583808765ef24fbbc8d126131be9adabea8230db7
name: matrix-static
-version: 0.2.1
+version: 0.3
synopsis: Type-safe matrix operations
description: Please see the README on GitHub at <https://github.com/wchresta/matrix-static#readme>
category: Math
@@ -15,10 +15,10 @@ homepage: https://github.com/wchresta/matrix-static#readme
bug-reports: https://github.com/wchresta/matrix-static/issues
author: Wanja Chresta
maintainer: wanja.hs@chrummibei.ch
-copyright: 2018, Wanja Chresta
+copyright: 2020, Wanja Chresta
license: BSD3
license-file: LICENSE
-tested-with: GHC == 8.6.1, GHC == 8.4.3, GHC == 8.2.2, GHC == 8.0.2, GHC == 8.0.1
+tested-with: GHC == 8.8.2, GHC == 8.6.5, GHC == 8.6.4, GHC == 8.4.4, GHC == 8.2.2, GHC == 8.0.2
build-type: Simple
extra-source-files:
README.md
diff --git a/src/Data/Matrix/Static.hs b/src/Data/Matrix/Static.hs
index c620862..b57ca4a 100644
--- a/src/Data/Matrix/Static.hs
+++ b/src/Data/Matrix/Static.hs
@@ -106,9 +106,11 @@ module Data.Matrix.Static (
) where
+import Control.Applicative (Applicative(..), liftA2)
import Control.DeepSeq (NFData)
import Data.Kind (Type)
import Data.Maybe (fromMaybe)
+import Data.Monoid (Monoid(..))
import Data.Proxy (Proxy(..))
import GHC.TypeLits
( Nat, KnownNat, natVal
@@ -123,14 +125,20 @@ import qualified Data.Vector as V
-- the 'Data.Matrix.Static.Matrix' constructor and adds size information to
-- the type
newtype Matrix (m :: Nat) (n :: Nat) (a :: Type) = Matrix (M.Matrix a)
- deriving ( Eq, Functor, Applicative, Foldable, Traversable
- , Monoid, NFData
- )
+ deriving ( Eq, Functor, Foldable, Traversable , NFData )
+
#if MIN_VERSION_base(4,10,0)
-instance Monoid a => S.Semigroup (Matrix m n a) where
- (<>) = applyBinary mappend
+instance (KnownNat m, KnownNat n, Monoid a) => S.Semigroup (Matrix m n a) where
+ (<>) = mappend
#endif
+instance (KnownNat m, KnownNat n) => Applicative (Matrix m n) where
+ pure a = matrix (const a)
+ m <*> n = matrix (\ij -> (m!ij) (n!ij))
+
+instance (KnownNat m, KnownNat n, Monoid a) => Monoid (Matrix m n a) where
+ mempty = pure mempty
+ mappend = liftA2 mappend
nrows :: forall m n a. KnownNat m => Matrix m n a -> Int
nrows = const m
diff --git a/test/Spec.hs b/test/Spec.hs
index 71a71b5..b803de6 100644
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -4,6 +4,7 @@
module Main where
import Data.Matrix.Static
+import Data.Monoid (Sum(Sum), Product(Product), (<>))
import Test.Tasty
import Test.Tasty.HUnit
@@ -11,7 +12,33 @@ main :: IO ()
main = defaultMain tests
tests :: TestTree
-tests = testGroup "Unit Tests" [ docExamples ]
+tests = testGroup "Unit Tests" [ docExamples, instanceTests ]
+
+instanceTests :: TestTree
+instanceTests =
+ let u = fromListUnsafe @2 @2 @(Int -> Int) (map (*) [1,2,3,4])
+ v = fromListUnsafe @2 @2 @(Int -> Int) (map (+) [3,-4,0,2])
+ w = fromListUnsafe @2 @2 @Int [4,-1,2,2]
+ a = fromListUnsafe @2 @2 @(Sum Int) (map Sum [-1,-4,0,2])
+ x = 2
+ f = (+5)
+ p = fromListUnsafe @2 @2 @Int [2,2,2,2]
+ in testGroup "Instance Tests"
+ [ testGroup "Applicative laws"
+ [ testCase "identitiy" $ pure id <*> w @?= w
+ , testCase "composition" $ pure (.) <*> u <*> v <*> w @?= u <*> (v <*> w)
+ , testCase "homomorphism" $ pure f <*> pure x @?= (pure (f x) :: Matrix 2 2 Int)
+ , testCase "interchange" $ u <*> pure x @?= (pure ($ x) <*> u :: Matrix 2 2 Int)
+ ]
+ , testGroup "Monoidal laws"
+ [ testCase "right identity" $ a <> mempty @?= a
+ , testCase "left identity" $ mempty <> a @?= a
+ , testCase "associativity" $
+ let b = fromListUnsafe @2 @2 @(Sum Int) (map Sum [-1,-4,0,2])
+ c = fromListUnsafe @2 @2 @(Sum Int) (map Sum [-1,-4,0,2])
+ in (a <> b) <> c @?= a <> (b <> c)
+ ]
+ ]
docExamples :: TestTree
docExamples =
@@ -38,7 +65,7 @@ docExamples =
zero @2 @2 @Int @?= fromListUnsafe [0,0,0,0]
, testCase "matrix" $
(matrix (\(i,j) -> 2*i-j) :: Matrix 2 4 Int) @?=
- fromListUnsafe [1,0,(-1),(-2),3,2,1,0]
+ fromListUnsafe [1,0,-1,-2,3,2,1,0]
, testCase "identity" $
identity @3 @Int @?=
fromListUnsafe [1,0,0,0,1,0,0,0,1]
@@ -123,3 +150,5 @@ docExamples =
, testCase "diagProd" $
diagProd mat33 @?= 45
]
+
+