diff --git a/Data/Packer/IEEE754.hs b/Data/Packer/IEEE754.hs
--- a/Data/Packer/IEEE754.hs
+++ b/Data/Packer/IEEE754.hs
@@ -5,13 +5,17 @@
 -- Stability   : experimental
 -- Portability : unknown
 --
--- IEEE-754 parsing, lifted from the cereal package by Christian Marie <pingu@ponies.io>
+-- fully rewritten to use primops.
 --
+-- original implementation based on IEEE-754 parsing, lifted from the cereal package by Christian Marie <pingu@ponies.io>
 -- Implementation is described here:
 -- <http://stackoverflow.com/questions/6976684/converting-ieee-754-floating-point-in-haskell-word32-64-to-and-from-haskell-float/7002812#7002812>
 --
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE BangPatterns #-}
 
 module Data.Packer.IEEE754 (
       wordToDouble
@@ -21,34 +25,45 @@
 ) where
 
 import Control.Monad.ST (runST, ST)
-
-import Data.Array.ST (newArray, readArray, MArray, STUArray)
 import Data.Word (Word32, Word64)
 
-#if __GLASGOW_HASKELL__ >= 704
-import Data.Array.Unsafe (castSTUArray)
-#else
-import Data.Array.ST (castSTUArray)
-#endif
+import GHC.Prim
+import GHC.Float
+import GHC.Word
+import GHC.ST
 
-{-# INLINE wordToFloat #-}
 wordToFloat :: Word32 -> Float
-wordToFloat x = runST (cast x)
+wordToFloat (W32# x) = runST $ ST $ \s1 ->
+    case newByteArray# 4# s1 of
+        (# s2, mbarr #) ->
+            let !s3 = writeWord32Array# mbarr 0# x s2
+             in case readFloatArray# mbarr 0# s3 of
+                    (# s4, f #) -> (# s4, F# f #)
+{-# INLINE wordToFloat #-}
 
-{-# INLINE floatToWord #-}
 floatToWord :: Float -> Word32
-floatToWord x = runST (cast x)
+floatToWord (F# x) = runST $ ST $ \s1 ->
+    case newByteArray# 4# s1 of
+        (# s2, mbarr #) ->
+            let !s3 = writeFloatArray# mbarr 0# x s2
+             in case readWord32Array# mbarr 0# s3 of
+                    (# s4, w #) -> (# s4, W32# w #)
+{-# INLINE floatToWord #-}
 
-{-# INLINE wordToDouble #-}
 wordToDouble :: Word64 -> Double
-wordToDouble x = runST (cast x)
+wordToDouble (W64# x) = runST $ ST $ \s1 ->
+    case newByteArray# 8# s1 of
+        (# s2, mbarr #) ->
+            let !s3 = writeWord64Array# mbarr 0# x s2
+             in case readDoubleArray# mbarr 0# s3 of
+                    (# s4, f #) -> (# s4, D# f #)
+{-# INLINE wordToDouble #-}
 
-{-# INLINE doubleToWord #-}
 doubleToWord :: Double -> Word64
-doubleToWord x = runST (cast x)
-
-{-# INLINE cast #-}
-cast :: (MArray (STUArray s) a (ST s),
-         MArray (STUArray s) b (ST s)) =>
-        a -> ST s b
-cast x = newArray (0 :: Int, 0) x >>= castSTUArray >>= flip readArray 0
+doubleToWord (D# x) = runST $ ST $ \s1 ->
+    case newByteArray# 8# s1 of
+        (# s2, mbarr #) ->
+            let !s3 = writeDoubleArray# mbarr 0# x s2
+             in case readWord64Array# mbarr 0# s3 of
+                    (# s4, w #) -> (# s4, W64# w #)
+{-# INLINE doubleToWord #-}
diff --git a/packer.cabal b/packer.cabal
--- a/packer.cabal
+++ b/packer.cabal
@@ -1,5 +1,5 @@
 Name:                packer
-Version:             0.1.6
+Version:             0.1.7
 Description:         Fast byte serializer and unserializer
 License:             BSD3
 License-file:        LICENSE
@@ -16,7 +16,7 @@
 Library
   Build-Depends:     base >= 3 && < 5
                    , bytestring
-                   , array
+                   , ghc-prim
                    , mtl
   Exposed-modules:   Data.Packer
                      Data.Packer.Unsafe
