diff --git a/Stack.cabal b/Stack.cabal
--- a/Stack.cabal
+++ b/Stack.cabal
@@ -1,11 +1,11 @@
-name: Stack
-version: 0.3.2
 cabal-version: >=1.10
-build-type: Simple
+name: Stack
+version: 0.4.0
 license: BSD3
 license-file: LICENSE
 copyright: 2016 Robert Walker
 maintainer: rwlock404@yahoo.com
+author: Robert Walker
 homepage: https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
 synopsis: Stack data structure
 description:
@@ -13,7 +13,7 @@
     .
     <<https://upload.wikimedia.org/wikipedia/commons/b/b4/Lifo_stack.png>>
 category: Data Structures
-author: Robert Walker
+build-type: Simple
 
 source-repository head
     type: git
@@ -22,13 +22,12 @@
 library
     exposed-modules:
         Data.Stack
-        Data.Stack.ST
         Control.Concurrent.STM.Stack
         Control.Concurrent.Stack
+    hs-source-dirs: src
+    default-language: Haskell2010
     build-depends:
         base >=4.7 && <5,
-        nats >=1.1.1 && <1.2,
-        stm >=2.4.4.1 && <2.5
-    default-language: Haskell2010
-    hs-source-dirs: src
-
+        nats >=1.1.2 && <1.2,
+        stm >=2.5.0.0 && <2.6,
+        deepseq >=1.4.4.0 && <1.5
diff --git a/src/Data/Stack.hs b/src/Data/Stack.hs
--- a/src/Data/Stack.hs
+++ b/src/Data/Stack.hs
@@ -18,10 +18,20 @@
   )
   where
 
+import Control.DeepSeq
 import Numeric.Natural
 
 -- | Abstract Stack data type
 data Stack a = Stack !Natural [a] deriving (Read,Show)
+
+instance (NFData a) => NFData (Stack a) where
+    rnf (Stack sz items) = sz `deepseq` items `deepseq` ()
+
+instance Semigroup (Stack a) where
+    (Stack sz1 items1) <> (Stack sz2 items2) = Stack (sz1+sz2) (items1 <> items2)
+
+instance Monoid (Stack a) where
+    mempty = Stack 0 []
 
 -- | /O(1)/. Create new empty Stack
 stackNew :: Stack a
diff --git a/src/Data/Stack/ST.hs b/src/Data/Stack/ST.hs
deleted file mode 100644
--- a/src/Data/Stack/ST.hs
+++ /dev/null
@@ -1,56 +0,0 @@
--- | Provides a stack container for use in the 'ST' monad
-module Data.Stack.ST (
-    Stack,
-    stackNew,
-    stackPush,
-    stackPeek,
-    stackPop,
-    stackIsEmpty,
-    stackSize,
-  )
-  where
-
-import Data.STRef
-import Control.Monad.ST
-import qualified Data.Stack as Pure
-import Numeric.Natural
-
--- | A mutable stack in state thread s, containing values of type a
-newtype Stack s a = Stack (STRef s (Pure.Stack a))
-
--- | Create new empty Stack
-stackNew :: ST s (Stack s a)
-stackNew = do
-    stackRef <- newSTRef Pure.stackNew
-    return (Stack stackRef)
-
--- | Push item onto Stack
-stackPush :: Stack s a -> a -> ST s ()
-stackPush (Stack stackRef) item = modifySTRef' stackRef (\stack -> Pure.stackPush stack item)
-
--- | Pop most recently added item without removing from the Stack
-stackPeek :: Stack s a -> ST s (Maybe a)
-stackPeek (Stack stackRef) = do
-    stack <- readSTRef stackRef
-    return (Pure.stackPeek stack)
-
--- | Pop most recently added item from Stack
-stackPop :: Stack s a -> ST s (Maybe a)
-stackPop (Stack stackRef) = do
-    stack <- readSTRef stackRef
-    case Pure.stackPop stack of
-      Just (stack1,item) -> do writeSTRef stackRef stack1
-                               return (Just item)
-      Nothing -> return Nothing
-
--- | Test if stack is empty
-stackIsEmpty :: Stack s a -> ST s Bool
-stackIsEmpty (Stack stackRef) = do
-    stack <- readSTRef stackRef
-    return (Pure.stackIsEmpty stack)
-
--- | Compute number of elements contained in the Stack
-stackSize :: Stack s a -> ST s Natural
-stackSize (Stack stackRef) = do
-    stack <- readSTRef stackRef
-    return (Pure.stackSize stack)
