diff --git a/CONTRIBUTORS b/CONTRIBUTORS
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1,3 +1,4 @@
 Ivar Nymoen <ivar.nymoen@gmail.com>
 João Cristóvão <jmacristovao@gmail.com>
 Jakub Stasiak <jakub@stasiak.at>
+Will Martino <wjmartino@gmail.com>
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 This is a Haskell binding for the nanomsg library: <http://nanomsg.org/>.
 
-There's support for [blocking](http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent.html#v:threadWaitRead) send and recv, a non-blocking receive,
+There's support for [(evented)](http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent.html#v:threadWaitRead) blocking send and recv, a non-blocking receive,
 and for all the socket types and the functions you need to wire them up and
 tear them down again.
 
@@ -13,8 +13,7 @@
 ## Building
 
 You would normally make sure the nanomsg library is on your system and then
-install from Hackage using "cabal update && cabal install nanomsg-haskell",
-but can build from the repository following these steps:
+install from Hackage, but can build from source following these steps:
 
   1. Build and install nanomsg (and zeromq, if you are building benchmarks)
   1. git clone https://github.com/ivarnymoen/nanomsg-haskell
@@ -39,10 +38,10 @@
 import Control.Concurrent (threadDelay)
 
 main :: IO ()
-main = do
+main =
     withSocket Pub $ \s -> do
         _ <- bind s "tcp://*:5560"
-        mapM_ (\num -> sendNumber s num) (cycle [1..1000000])
+        mapM_ (\num -> sendNumber s num) (cycle [1..1000000 :: Int])
     where
         sendNumber s number = do
             threadDelay 1000        -- let's conserve some cycles
@@ -59,7 +58,7 @@
 import Control.Monad (forever)
 
 main :: IO ()
-main = do
+main =
     withSocket Sub $ \s -> do
         _ <- connect s "tcp://localhost:5560"
         subscribe s $ C.pack ""
@@ -87,5 +86,5 @@
             msg <- recv' s
             C.putStrLn $ case msg of
                 Nothing -> C.pack "No message"
-                Just s  -> s
+                Just m  -> m
 ```
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,4 +1,8 @@
+0.2.3
+  * Switched to safe ffi calls to play better with the runtime
+  * Tests fixed for ghc 7.10
+  * Some minor tweaks to docs and metadata
 0.2.2
-  * Added a thin binary based serialization layer
+  * Added a thin Binary based serialization layer
   * Benchmarks now depend on ZMQ4
 
diff --git a/nanomsg-haskell.cabal b/nanomsg-haskell.cabal
--- a/nanomsg-haskell.cabal
+++ b/nanomsg-haskell.cabal
@@ -1,20 +1,17 @@
 name:                nanomsg-haskell
-version:             0.2.2
+version:             0.2.3
 synopsis:
   Bindings to the nanomsg library
 description:
   This is a Haskell binding for the nanomsg library: <http://nanomsg.org/>.
-
+  .
   There's support for (evented) blocking send and recv, a non-blocking receive,
   and for all the socket types and the functions you need to wire
   them up and tear them down again.
-
+  .
   Most sockets options are available through accessor and mutator
   functions. Sockets are typed, transports are not.
 
-  The module Nanomsg.Binary provides a simple Binary based serialization
-  layer over send and receive.
-
 homepage:            https://github.com/ivarnymoen/nanomsg-haskell
 license:             MIT
 license-file:        LICENSE
@@ -24,19 +21,22 @@
 category:            Network
 build-type:          Simple
 cabal-version:       >=1.10
+tested-with:
+  GHC == 7.10.2
 extra-source-files:
-    README.md
-    , CONTRIBUTORS
-    , changelog
-    , tests/*.hs
-    , benchmarks/*.hs
+  README.md
+  , CONTRIBUTORS
+  , changelog
+  , tests/*.hs
+  , benchmarks/*.hs
 
 library
   hs-source-dirs:    src
-  ghc-options:       -O2 -Wall
+  ghc-options:       -O2 -Wall -fwarn-tabs
   default-language:  Haskell2010
-  exposed-modules:   Nanomsg
-                     Nanomsg.Binary
+  exposed-modules:
+    Nanomsg
+    Nanomsg.Binary
   default-extensions:  ForeignFunctionInterface, DeriveDataTypeable
   includes:          nanomsg/nn.h
   extra-libraries:   nanomsg
@@ -49,7 +49,7 @@
   type:              exitcode-stdio-1.0
   hs-source-dirs:    tests
   main-is:           Properties.hs
-  ghc-options:       -O2 -Wall -threaded
+  ghc-options:       -O2 -Wall -fwarn-tabs -threaded "-with-rtsopts=-N" -rtsopts
   default-language:  Haskell2010
   build-depends:
     base >= 4.5 && < 5,
@@ -64,7 +64,7 @@
   type:              exitcode-stdio-1.0
   hs-source-dirs:    tests
   main-is:           BinaryProperties.hs
-  ghc-options:       -O2 -Wall -threaded
+  ghc-options:       -O2 -Wall -fwarn-tabs -threaded "-with-rtsopts=-N" -rtsopts
   default-language:  Haskell2010
   build-depends:
     base >= 4.5 && < 5,
@@ -76,7 +76,6 @@
     test-framework-quickcheck2,
     test-framework-th
 
-
 source-repository head
   type:              git
   location:          https://github.com/ivarnymoen/nanomsg-haskell
@@ -84,7 +83,7 @@
 benchmark send-messages
   type:              exitcode-stdio-1.0
   main-is:           SendMessages.hs
-  ghc-options:       -O2 -Wall -threaded
+  ghc-options:       -O2 -Wall -fwarn-tabs -threaded "-with-rtsopts=-N" -rtsopts
   default-language:  Haskell2010
   hs-source-dirs:    benchmarks
   build-depends:
@@ -96,7 +95,7 @@
 benchmark vs-zeromq-bindings
   type:              exitcode-stdio-1.0
   main-is:           Zmq.hs
-  ghc-options:       -O2 -Wall -threaded
+  ghc-options:       -O2 -Wall -fwarn-tabs -threaded "-with-rtsopts=-N" -rtsopts
   default-language:  Haskell2010
   hs-source-dirs:    benchmarks
   build-depends:
diff --git a/src/Nanomsg.hsc b/src/Nanomsg.hsc
--- a/src/Nanomsg.hsc
+++ b/src/Nanomsg.hsc
@@ -327,52 +327,52 @@
 -- * FFI functions
 
 -- NN_EXPORT int nn_socket (int domain, int protocol);
-foreign import ccall unsafe "nn.h nn_socket"
+foreign import ccall safe "nn.h nn_socket"
     c_nn_socket :: CInt -> CInt -> IO CInt
 
 -- NN_EXPORT int nn_bind (int s, const char *addr);
-foreign import ccall unsafe "nn.h nn_bind"
+foreign import ccall safe "nn.h nn_bind"
     c_nn_bind :: CInt -> CString -> IO CInt
 
 -- NN_EXPORT int nn_connect (int s, const char *addr);
-foreign import ccall unsafe "nn.h nn_connect"
+foreign import ccall safe "nn.h nn_connect"
     c_nn_connect :: CInt -> CString -> IO CInt
 
 -- NN_EXPORT int nn_shutdown (int s, int how);
-foreign import ccall unsafe "nn.h nn_shutdown"
+foreign import ccall safe "nn.h nn_shutdown"
     c_nn_shutdown :: CInt -> CInt -> IO CInt
 
 -- NN_EXPORT int nn_send (int s, const void *buf, size_t len, int flags);
-foreign import ccall unsafe "nn.h nn_send"
+foreign import ccall safe "nn.h nn_send"
     c_nn_send :: CInt -> CString -> CInt -> CInt -> IO CInt
 
 -- NN_EXPORT int nn_recv (int s, void *buf, size_t len, int flags);
-foreign import ccall unsafe "nn.h nn_recv"
+foreign import ccall safe "nn.h nn_recv"
     c_nn_recv :: CInt -> Ptr CString -> CInt -> CInt -> IO CInt
 
 -- NN_EXPORT int nn_freemsg (void *msg);
-foreign import ccall unsafe "nn.h nn_freemsg"
+foreign import ccall safe "nn.h nn_freemsg"
     c_nn_freemsg :: Ptr CChar -> IO CInt
 
 -- NN_EXPORT int nn_close (int s);
-foreign import ccall unsafe "nn.h nn_close"
+foreign import ccall safe "nn.h nn_close"
     c_nn_close :: CInt -> IO CInt
 
 -- NN_EXPORT void nn_term (void);
-foreign import ccall unsafe "nn.h nn_term"
+foreign import ccall safe "nn.h nn_term"
     c_nn_term :: IO ()
 
 -- NN_EXPORT int nn_setsockopt (int s, int level, int option, const void *optval, size_t optvallen);
-foreign import ccall unsafe "nn.h nn_setsockopt"
+foreign import ccall safe "nn.h nn_setsockopt"
     c_nn_setsockopt :: CInt -> CInt -> CInt -> Ptr a -> CInt -> IO CInt
 
 -- NN_EXPORT int nn_getsockopt (int s, int level, int option, void *optval, size_t *optvallen);
-foreign import ccall unsafe "nn.h nn_getsockopt"
+foreign import ccall safe "nn.h nn_getsockopt"
     c_nn_getsockopt :: CInt -> CInt -> CInt -> Ptr a -> Ptr CInt -> IO CInt
 
 -- /*  Resolves system errors and native errors to human-readable string.        */
 -- NN_EXPORT const char *nn_strerror (int errnum);
-foreign import ccall unsafe "nn.h nn_strerror"
+foreign import ccall safe "nn.h nn_strerror"
     c_nn_strerror :: CInt -> IO CString
 
 -- /*  This function retrieves the errno as it is known to the library.          */
@@ -380,7 +380,7 @@
 -- /*  where the library is compiled with certain CRT library (on Windows) and   */
 -- /*  linked to an application that uses different CRT library.                 */
 -- NN_EXPORT int nn_errno (void);
-foreign import ccall unsafe "nn.h nn_errno"
+foreign import ccall safe "nn.h nn_errno"
     c_nn_errno :: IO CInt
 
 {-
diff --git a/tests/Properties.hs b/tests/Properties.hs
--- a/tests/Properties.hs
+++ b/tests/Properties.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Main where
 
@@ -24,7 +25,7 @@
 -- test Pub and Sub sockets
 prop_PubSub :: Property
 prop_PubSub = monadicIO $ do
-    msgs <- pick arbitrary
+    (msgs :: [ByteString]) <- pick arbitrary
     pre $ not (null msgs)
     res <- run $ do
         pub <- socket Pub
@@ -61,7 +62,7 @@
 -- test Pair sockets
 prop_Pair :: Property
 prop_Pair = monadicIO $ do
-    msgs <- pick arbitrary
+    (msgs :: [ByteString]) <- pick arbitrary
     pre $ not (null msgs)
     res <- run $ do
         s1 <- socket Pair
@@ -80,7 +81,7 @@
 -- test Pipeline (Push & Pull) sockets
 prop_Pipeline :: Property
 prop_Pipeline = monadicIO $ do
-    msgs <- pick arbitrary
+    (msgs :: [ByteString]) <- pick arbitrary
     pre $ not (null msgs)
     res <- run $ do
         push <- socket Push
@@ -115,7 +116,7 @@
 -- test Req and Rep sockets
 prop_ReqRep :: Property
 prop_ReqRep = monadicIO $ do
-    msgs <- pick arbitrary
+    (msgs :: [ByteString]) <- pick arbitrary
     pre $ not (null msgs)
     res <- run $ do
         req <- socket Req
@@ -133,7 +134,7 @@
 -- test Bus socket
 prop_Bus :: Property
 prop_Bus = monadicIO $ do
-    msgs <- pick arbitrary
+    (msgs :: [ByteString]) <- pick arbitrary
     pre $ not (null msgs)
     res <- run $ do
         -- Probably not how you're supposed to connect Bus nodes..
