diff --git a/Stack.cabal b/Stack.cabal
--- a/Stack.cabal
+++ b/Stack.cabal
@@ -1,5 +1,5 @@
 name:                Stack
-version:             0.3.0
+version:             0.3.1
 synopsis:            Stack data structure
 description:         A stack is a basic data structure that can be logically thought as linear structure represented by a real physical stack or pile, a structure where insertion and deletion of items takes place at one end called top of the stack.
                      .
@@ -19,7 +19,6 @@
   exposed-modules:     Data.Stack, Control.Concurrent.STM.Stack, Control.Concurrent.Stack
   build-depends:       base >= 4.7 && < 5, nats, stm
   default-language:    Haskell2010
-  ghc-options: -Wall
 
 source-repository head
   type:     git
diff --git a/src/Control/Concurrent/STM/Stack.hs b/src/Control/Concurrent/STM/Stack.hs
--- a/src/Control/Concurrent/STM/Stack.hs
+++ b/src/Control/Concurrent/STM/Stack.hs
@@ -1,4 +1,4 @@
--- | Provides a synchronized stack for use in the STM monad
+-- | Provides a synchronized stack container for use in the 'STM' monad
 --
 -- See also "Control.Concurrent.Stack"
 module Control.Concurrent.STM.Stack (
@@ -16,69 +16,66 @@
 
 import Control.Concurrent.STM.TVar
 import Control.Monad.STM
+import qualified Data.Stack as Pure
 import Numeric.Natural
 
 -- | Synchronized stack data type
-data Stack a = Stack (TVar [a])
+newtype Stack a = Stack (TVar (Pure.Stack a))
 
 -- | Create new Stack
 stackNew :: STM (Stack a)
 stackNew = do
-    items <- newTVar []
-    return (Stack items)
+    stackRef <- newTVar Pure.stackNew
+    return (Stack stackRef)
 
 -- | Push item onto Stack
 stackPush :: Stack a -> a -> STM ()
-stackPush (Stack itemsVar) item = do
-    items <- readTVar itemsVar
-    writeTVar itemsVar (item:items)
+stackPush (Stack stackRef) item = modifyTVar' stackRef (\stack -> Pure.stackPush stack item)
 
 -- | Pop most recently added item without removing from the Stack
 stackTryPeek :: Stack a -> STM (Maybe a)
-stackTryPeek (Stack itemsVar) = do
-    items <- readTVar itemsVar
-    if null items
-        then return Nothing
-        else return (Just (head items))
+stackTryPeek (Stack stackRef) = do
+    stack <- readTVar stackRef
+    return (Pure.stackPeek stack)
 
 -- | Pop most recently added item without removing from the Stack
 --
 -- Automatically retries if stack is empty
 stackPeek :: Stack a -> STM a
-stackPeek (Stack itemsVar) = do
-    items <- readTVar itemsVar
-    if null items
-        then retry
-        else return (head items)
+stackPeek (Stack stackRef) = do
+    stack <- readTVar stackRef
+    case Pure.stackPeek stack of
+      Just item -> return item
+      Nothing   -> retry
 
 -- | Pop most recently added item from Stack
 stackTryPop :: Stack a -> STM (Maybe a)
-stackTryPop (Stack itemsVar) = do
-    items <- readTVar itemsVar
-    if null items
-        then return Nothing
-        else do writeTVar itemsVar (tail items)
-                return (Just (head items))
+stackTryPop (Stack stackRef) = do
+    stack <- readTVar stackRef
+    case Pure.stackPop stack of
+      Just (stack1,item) -> do writeTVar stackRef stack1
+                               return (Just item)
+      Nothing -> return Nothing
 
 -- | Pop most recently added item from Stack
 --
 -- Automatically retries if stack is empty
 stackPop :: Stack a -> STM a
-stackPop (Stack itemsVar) = do
-    items <- readTVar itemsVar
-    if null items
-        then retry
-        else do writeTVar itemsVar (tail items)
-                return (head items)
+stackPop (Stack stackRef) = do
+    stack <- readTVar stackRef
+    case Pure.stackPop stack of
+      Just (stack1,item) -> do writeTVar stackRef stack1
+                               return item
+      Nothing -> retry
 
 -- | Test if stack is empty
 stackIsEmpty :: Stack a -> STM Bool
-stackIsEmpty (Stack itemsVar) = do
-    items <- readTVar itemsVar
-    if null items then return True else return False
+stackIsEmpty (Stack stackRef) = do
+    stack <- readTVar stackRef
+    return (Pure.stackIsEmpty stack)
 
 -- | Compute number of elements contained in the Stack
 stackSize :: Stack a -> STM Natural
-stackSize (Stack itemsVar) = do
-    items <- readTVar itemsVar
-    return (fromIntegral (length items))
+stackSize (Stack stackRef) = do
+    stack <- readTVar stackRef
+    return (Pure.stackSize stack)
diff --git a/src/Data/Stack.hs b/src/Data/Stack.hs
--- a/src/Data/Stack.hs
+++ b/src/Data/Stack.hs
@@ -21,47 +21,47 @@
 import Numeric.Natural
 
 -- | Abstract Stack data type
-data Stack a = Stack [a] deriving (Read,Show)
+data Stack a = Stack !Natural [a] deriving (Read,Show)
 
--- | Create new Stack
+-- | /O(1)/. Create new Stack
 stackNew :: Stack a
-stackNew = Stack []
+stackNew = Stack 0 []
 
--- | Push item onto Stack
+-- | /O(1)/. Push item onto Stack
 --
 -- > (∀x)(∀s)(stackPop (stackPush s x) == Just (s,x))
 stackPush :: Stack a -> a -> Stack a
-stackPush (Stack items) item = Stack (item : items)
+stackPush (Stack sz items) item = Stack (succ sz) (item : items)
 
--- | Pop most recently added item without removing from the Stack
+-- | /O(1)/. Pop most recently added item without removing from the Stack
 --
 -- > stackPeek stackNew == Nothing
 -- > (∀x)(∀s)(stackPeek (stackPush s x) == Just x)
 -- > (∀s)(stackPeek s == fmap snd (stackPop s))
 stackPeek :: Stack a -> Maybe a
-stackPeek (Stack []) = Nothing
-stackPeek (Stack items) = Just (head items)
+stackPeek (Stack _ []) = Nothing
+stackPeek (Stack _ items) = Just (head items)
 
--- | Pop most recently added item from Stack
+-- | /O(1)/. Pop most recently added item from Stack
 --
 -- > stackPop stackNew == Nothing
 -- > (∀x)(∀s)(stackPop (stackPush s x) == Just (s,x))
 stackPop :: Stack a -> Maybe (Stack a, a)
-stackPop (Stack []) = Nothing
-stackPop (Stack items) = Just (Stack (tail items), head items)
+stackPop (Stack _ []) = Nothing
+stackPop (Stack sz items) = Just (Stack (pred sz) (tail items), head items)
 
--- | Test if stack is empty
+-- | /O(1)/. Test if stack is empty
 --
 -- > stackIsEmpty stackNew == True
 -- > (∀x)(∀s)(stackIsEmpty (stackPush s x) == True)
 -- > (∀s)((stackSize s == 0) ⇔ (stackIsEmpty s == True))
 stackIsEmpty :: Stack a -> Bool
-stackIsEmpty (Stack []) = True
-stackIsEmpty (Stack _)  = False
+stackIsEmpty (Stack _ []) = True
+stackIsEmpty (Stack _ _)  = False
 
--- | Compute number of elements contained in the Stack
+-- | /O(1)/. Compute number of elements contained in the Stack
 --
 -- > stackSize stackNew == 0
 -- > (∀x)(∀s)((stackSize s == n) ⇒ (stackSize (stackPush s x) == n+1))
 stackSize :: Stack a -> Natural
-stackSize (Stack items) = fromIntegral (length items)
+stackSize (Stack sz _) = sz
