diff --git a/ChangeLog.md b/ChangeLog.md
--- 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
--- a/README.md
+++ b/README.md
@@ -2,10 +2,11 @@
 [![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.
 
diff --git a/matrix-static.cabal b/matrix-static.cabal
--- a/matrix-static.cabal
+++ b/matrix-static.cabal
@@ -4,10 +4,10 @@
 --
 -- 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 @@
 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
--- a/src/Data/Matrix/Static.hs
+++ b/src/Data/Matrix/Static.hs
@@ -106,9 +106,11 @@
 
   ) 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 @@
 --   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
--- 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,8 +12,34 @@
 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 =
   let mat33 = fromListUnsafe @3 @3 @Int [1..9]
@@ -38,7 +65,7 @@
       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 @@
   , testCase "diagProd" $
       diagProd mat33 @?= 45
   ]
+
+
