diff --git a/Data/PerfectHash.lhs b/Data/PerfectHash.lhs
--- a/Data/PerfectHash.lhs
+++ b/Data/PerfectHash.lhs
@@ -1,17 +1,19 @@
 > {-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables, EmptyDataDecls, BangPatterns, TypeSynonymInstances, FlexibleInstances #-}
-> module Data.PerfectHash ( PerfectHash, fromList, lookup, lookupByIndex ) where
 
-> import Array
-> import Data.Array.IO
-> import Foreign
+> module Data.PerfectHash ( PerfectHash, fromList, lookup, lookupByIndex ) where
+>
+> import Data.Array.Unsafe (unsafeFreeze)
+> import System.IO.Unsafe (unsafePerformIO)
+> import Data.Array
+> import Data.Array.IO (newArray_,writeArray,IOArray)
+> import Foreign(Ptr)
 > import Foreign.C.String
 > import Foreign.C.Types
 > import Foreign.Marshal.Array
 > import Prelude hiding (lookup)
-> import System.IO.Unsafe
 > import qualified Data.ByteString.Char8 as S
 > import qualified Data.ByteString.Unsafe as Unsafe
-> import Data.Array.Storable
+> import Data.Array.Storable (withStorableArray)
 > import Data.Binary
 > import Data.Digest.CRC32 (crc32)
 > import Data.Digest.Adler32 (adler32)
@@ -29,8 +31,8 @@
 
 > data ForeignHash
 
-> data PerfectHash a = PerfectHash { store     :: !(Array.Array Word32 (a,CString)),
->                                    cmph      :: Ptr ForeignHash 
+> data PerfectHash a = PerfectHash { store     :: !(Array Word32 (a,CString)),
+>                                    cmph      :: Ptr ForeignHash
 >                                  }
 
 is this even a sane thing to do?
@@ -43,7 +45,7 @@
 -- >     get = do
 -- >           size <- get
 -- >           arr <- newArray_ (0,size)
--- >           forM_ [0 .. size] $ writeArray arr 
+-- >           forM_ [0 .. size] $ writeArray arr
 -- >           store <- get
 -- >           cmph <- undefined
 -- >           return $ PerfectHash { store = store, cmph = cmph }
@@ -70,10 +72,10 @@
 >                   (fodder,cstr_ptrs) <- prepareCPtrs
 >                   cmph <- withStorableArray fodder $ \ptr -> c_build_hash ptr (fromIntegral len)
 >                   i_arr <- buildArray cmph cstr_ptrs
->                   return PerfectHash { store = i_arr, 
+>                   return PerfectHash { store = i_arr,
 >                                        cmph = cmph }
 
->   where prepareCPtrs = do 
+>   where prepareCPtrs = do
 >                   fodder <- newArray_ (0, len-1)
 >                   -- we make one pass over ls, then throw it away
 >                   cstr_ptrs <- mapM (\(i,(bs, val)) ->
@@ -83,27 +85,27 @@
 >                            return ((newPtr,fromIntegral len),val))
 >                         (zip [0..] ls)
 >                   return (fodder, cstr_ptrs)
->                          
+>
 >         buildArray cmph cstr_ptrs = do
 >                   arr <- newArray_ (fromIntegral 0, fromIntegral len - 1) :: IO (IOArray Word32 a)
 >                   mapM_ (\(cl@(cstr,len),val) -> writeArray arr (raw_hashfunc cmph cl) (val,cstr)) $ cstr_ptrs
 >                   -- we created it, we can do what we like with it...
 >                   unsafeFreeze arr
->                                
+>
 >         len = length ls
 
 > lookup :: PerfectHash a -> S.ByteString -> Maybe a
 > lookup !hash !bs = guard check >> return e
 >     where index = {-# SCC "hash_only" #-} use_hash (cmph hash) bs
->           (!low, !high) = Array.bounds arr
+>           (!low, !high) = bounds arr
 >           !arr = store hash
 >           (e, str) = arr ! index
 
 basic index checking stuff plus a check that we haven't just had a hash collision - tried crc checking here
 and it turns out that strncmp is faster
 
->           !check = {-# SCC "check" #-} low <= index && high >= index && 
->                   {-# SCC "bs_check" #-} unsafePerformIO $ Unsafe.unsafeUseAsCStringLen bs (\(cstr,len) -> 
+>           !check = {-# SCC "check" #-} low <= index && high >= index &&
+>                   {-# SCC "bs_check" #-} unsafePerformIO $ Unsafe.unsafeUseAsCStringLen bs (\(cstr,len) ->
 >                                               c_strncmp str cstr (fromIntegral len) >>= \res -> return (res == 0))
 
 >           use_hash a str = {-# SCC "use_hash" #-}  unsafePerformIO $ Unsafe.unsafeUseAsCStringLen str
diff --git a/PerfectHash.cabal b/PerfectHash.cabal
--- a/PerfectHash.cabal
+++ b/PerfectHash.cabal
@@ -1,6 +1,6 @@
 Name:           PerfectHash
-Version:        0.1.3
-Cabal-Version:  >= 1.2
+Version:        0.1.4
+Cabal-Version:  >= 1.6
 License:	BSD3
 License-File:   LICENSE
 Build-Type:     Simple
@@ -16,13 +16,22 @@
 		to the C-based CMPH library (http://cmph.sf.net). Only fromList
 		and lookup operations are supported, but in many circumstances
 		this is all that's required.
+
+                CI at https://travis-ci.org/mwotton/PerfectHash
 Library
         Exposed-Modules: Data.PerfectHash, HackedMicrobench
-        ghc-options:    -auto-all -funbox-strict-fields -fvia-C -optc-O2 
+        ghc-options:    -funbox-strict-fields
         c-sources: stub.c
         includes: stub.h
-        extra-lib-dirs: /usr/local/lib/
         extra-libraries: cmph
-        build-depends:  base, haskell98, containers, bytestring, digest,array, time, binary
-
+        build-depends:  base >=4.5 && <4.8,
+                        containers,
+                        bytestring,
+                        digest,
+                        array,
+                        time,
+                        binary
 
+source-repository head
+  type: git
+  location: http://github.com/mwotton/PerfectHash.git
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,4 +1,2 @@
-#!/usr/bin/env runhaskell
 import Distribution.Simple
-
 main = defaultMain
