diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+0.4.4: 15 Jan 2018: Fix compilation with mpfr-4.0.0.0
+0.4.3: 7 Aug 2017: expose all modules
+0.4.2.1: 28 Dec 2016: instance Generic MPFR
+0.4.2: 2nd Sep 2016: Added RealFloat instances
+0.4.1: 2nd Aug 2016: Added support for digamma
+0.4.: 11th Jul 2016: Compiles only with ghc 7.10 or newer
 0.3.3: 22 Dec 2011: Compiles with both integer-simple and integer-gmp (but mis-behaves with standard integer-gmp).
 0.3.2: 28 Feb 2011: Adapted to work with mpfr 3.0.0, now depends on integer-simple.
 0.3: 23 Sep 2009: Added mutable interface and removed some modules from the export list.
diff --git a/README b/README
deleted file mode 100644
--- a/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Haskell MPFR binding.
-
-If you find bugs or have any questions please write to <ales.bizjak0@gmail.com>.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+Haskell MPFR binding
diff --git a/cbits/chsmpfr.c b/cbits/chsmpfr.c
--- a/cbits/chsmpfr.c
+++ b/cbits/chsmpfr.c
@@ -20,7 +20,11 @@
   return state;
 }
 
+#if defined (_MPFR_PROTO)
 __MPFR_DECLSPEC int mpfr_urandomb_deref_randstate _MPFR_PROTO ((mpfr_ptr dP, gmp_randstate_t * rsP))
+#else
+__MPFR_DECLSPEC int mpfr_urandomb_deref_randstate (mpfr_ptr dP, gmp_randstate_t * rsP)
+#endif
 {
   return mpfr_urandomb(dP, * rsP);
 }
@@ -33,7 +37,7 @@
   return mpfr_inf_p(p);
 }
 int mpfr_zero_p_wrap(const mpfr_ptr p) {
-  return mpfr_zero_p(p); 
+  return mpfr_zero_p(p);
 }
 
 int mpfr_set_wrap(const mpfr_ptr p1, const mpfr_ptr p2, mp_rnd_t r) {
@@ -58,7 +62,7 @@
 
 int mpfr_sgn_wrap (const mpfr_ptr p1) {
   return mpfr_sgn (p1);
-} 
+}
 
 int mpfr_set_si_wrap (const mpfr_ptr p, long int si, mp_rnd_t r) {
   return mpfr_set_si(p, si, r);
@@ -105,7 +109,7 @@
 }
 
 size_t mpfr_custom_get_size_wrap (mp_prec_t p1) {
-  return mpfr_custom_get_size (p1); 
+  return mpfr_custom_get_size (p1);
 }
 
 void mpfr_custom_init_wrap (void *p1 , mp_prec_t p2) {
diff --git a/cbits/chsmpfr.h b/cbits/chsmpfr.h
--- a/cbits/chsmpfr.h
+++ b/cbits/chsmpfr.h
@@ -8,7 +8,11 @@
 
 gmp_randstate_t * new_gmp_randstate();
 
+#if defined (_MPFR_PROTO)
 __MPFR_DECLSPEC int mpfr_urandomb_deref_randstate _MPFR_PROTO ((mpfr_ptr dP, gmp_randstate_t * rsP));
+#else
+__MPFR_DECLSPEC int mpfr_urandomb_deref_randstate (mpfr_ptr dP, gmp_randstate_t * rsP);
+#endif
 
 // these functions are defined as macros and so haskell ffi 
 // can't work with them directly
diff --git a/hmpfr.cabal b/hmpfr.cabal
--- a/hmpfr.cabal
+++ b/hmpfr.cabal
@@ -1,73 +1,44 @@
+cabal-version:       3.0
 name:                hmpfr
-version:             0.3.3.5
+version:             0.4.5
 synopsis:            Haskell binding to the MPFR library
-description:         Haskell binding to the MPFR library. This version is compatible
-                     with MPFR 2.4.* and later and will not work with previous releases
-                     of the MPFR library.
-                     .
-                     /Since MPFR uses GMP, this library features infrequent but serious errors/
-                     /with a ghc that has been compiled with the default integer-gmp./  
-                     /When using ghc, it is recommended to use one compiled with a modified integer-gmp,/
-                     /as described at/ 
-                     .
-                     <http://code.google.com/p/hmpfr/wiki/GHCWithRenamedGMP>
-                     .
-                     /or/
-                     /with integer-simple, as described at/
-                     .
-                     <http://code.google.com/p/hmpfr/wiki/GHCWithoutGMP>
-                     .
-                     /There is a hope that at some point future versions of ghc will not need any modification for/
-                     /hmpfr to work with them correctly./
-                     .
-                     The library includes both a pure and a mutable interface.
-                     The mutable interface should have a lot less overhead 
-                     than the pure one.
-                     .
-                     Some simple examples of usage can be found in demo/Demo.hs.
+description:
+  Haskell binding to the MPFR library.
+  .
+  The library includes both a pure and a mutable interface.
+  The mutable interface should have a lot less overhead
+  than the pure one.
+  .
+  Some simple examples of usage can be found in demo/Demo.hs.
+
 category:            Data, Math
-license:             BSD3
+license:             BSD-3-Clause
 license-file:        LICENSE
 Stability:           experimental
 Tested-with:
-                GHC==6.12.3,
-                GHC==7.2.2,
-                GHC==7.4.1
+                GHC==9.0.2
+                GHC==9.2.5
+                GHC==9.4.3
 author:              Aleš Bizjak, Michal Konečný
 maintainer:          Michal Konečný <mikkonecny@gmail.com>
-Homepage:            http://code.google.com/p/hmpfr/
+Homepage:            https://github.com/michalkonecny/hmpfr
 build-type:          Simple
-cabal-version:       >= 1.6
 Extra-source-files:  demo/Demo.hs
 
-Data-files:          README
-                     dict.txt
-                     ChangeLog
+Data-files:
+  README.md
+  dict.txt
+  ChangeLog
 
 source-repository head
-  type:     mercurial
-  location: https://code.google.com/p/hmpfr/
-
-source-repository this
-  type:     mercurial
-  location: https://code.google.com/p/hmpfr/
-  tag:      release-0.3.3.5
-
-
-flag use-integer-simple
-  description: Use this when compiling using a ghc that uses integer-simple instead of integer-gmp.
-  default: False
+  type:     git
+  location: https://github.com/michalkonecny/hmpfr
 
 Library
-  build-Depends:       base > 3 && < 5
-  if flag(use-integer-simple)
-     build-Depends:    integer-simple
-     cpp-options: -DINTEGER_SIMPLE
-  else
-     build-Depends:    integer-gmp
-     cpp-options: -DINTEGER_GMP
+  build-Depends:       base >= 4.8 && < 5
 
-  Other-modules:       Data.Number.MPFR.FFIhelper
+  Exposed-modules:
+                       Data.Number.MPFR.FFIhelper
                        Data.Number.MPFR.Internal
                        Data.Number.MPFR.Mutable.Internal
 
@@ -75,7 +46,7 @@
                        Data.Number.MPFR.Mutable.Special
                        Data.Number.MPFR.Mutable.Integer
                        Data.Number.MPFR.Mutable.Misc
-                       
+
                        Data.Number.MPFR.Assignment
                        Data.Number.MPFR.Conversion
                        Data.Number.MPFR.Arithmetic
@@ -84,7 +55,7 @@
                        Data.Number.MPFR.Integer
                        Data.Number.MPFR.Misc
 
-  Exposed-modules:     Data.Number.MPFR.Instances.Near
+                       Data.Number.MPFR.Instances.Near
                        Data.Number.MPFR.Instances.Up
                        Data.Number.MPFR.Instances.Down
                        Data.Number.MPFR.Instances.Zero
@@ -92,10 +63,8 @@
                        Data.Number.MPFR
 
                        Data.Number.MPFR.Mutable
-                       
-  build-tools:         hsc2hs
+
   GHC-options:         -Wall -fno-warn-orphans
-  GHC-prof-options:    -prof -auto
   hs-source-dirs:      src
   include-dirs:        cbits
   includes:            mpfr.h
@@ -103,4 +72,4 @@
   c-sources:           cbits/chsmpfr.c
 
   extra-libraries:     mpfr
-
+  default-language:    Haskell2010
diff --git a/src/Data/Number/MPFR/Assignment.hs b/src/Data/Number/MPFR/Assignment.hs
--- a/src/Data/Number/MPFR/Assignment.hs
+++ b/src/Data/Number/MPFR/Assignment.hs
@@ -20,15 +20,7 @@
 
 import Data.Number.MPFR.Arithmetic
 
-#ifdef INTEGER_SIMPLE
-import GHC.Integer.Simple.Internals
-import Foreign.Storable (sizeOf)
-#endif
-
-#ifdef INTEGER_GMP
---import GHC.Integer.GMP.Internals
-import GHC.Float
-#endif
+import GHC.Num.Integer ( integerLogBase )
 
 set     :: RoundMode -> Precision -> MPFR -> MPFR
 set r p = fst . set_ r p
@@ -140,19 +132,7 @@
 
 bitsInInteger :: (Num a) => Integer -> a
 
-#  ifdef INTEGER_SIMPLE
-bitsInInteger Naught = 0
-bitsInInteger (Positive pos) = bitsInPositive pos
-bitsInInteger (Negative pos) = bitsInPositive pos
-bitsInPositive :: (Num a) => Positive -> a
-bitsInPositive None = 0
-bitsInPositive (Some _ rest) = 
-    (8 * sizeofInt) + (bitsInPositive rest)
-sizeofInt :: (Num a) => a 
-sizeofInt = fromIntegral $ sizeOf (0 :: Int) -- in bytes
-#else
-bitsInInteger = fromIntegral . GHC.Float.integerLogBase 2
-#endif
+bitsInInteger = fromIntegral . integerLogBase 2
 
 compose             :: RoundMode -> Precision -> (Integer, Int) -> MPFR 
 compose r p (i, ii) = div2i r p (fromIntegerA r p i) ii
diff --git a/src/Data/Number/MPFR/FFIhelper.hsc b/src/Data/Number/MPFR/FFIhelper.hsc
--- a/src/Data/Number/MPFR/FFIhelper.hsc
+++ b/src/Data/Number/MPFR/FFIhelper.hsc
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE ForeignFunctionInterface, DeriveGeneric, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
 #include <chsmpfr.h>
 #include <mpfr.h>
 
@@ -20,53 +20,54 @@
 import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrBytes)
 
 import Data.Typeable(Typeable)
+import GHC.Generics(Generic)
 
 import Data.Function(on)
-    
-data RoundMode = Near | Zero | Up | Down | MPFR_RNDNA 
+
+data RoundMode = Near | Zero | Up | Down | MPFR_RNDNA
                  deriving (Show, Read)
 
 instance Enum RoundMode where
 #if MPFR_VERSION_MAJOR == 2
-    fromEnum Near        = #{const GMP_RNDN} 
-    fromEnum Zero        = #{const GMP_RNDZ} 
-    fromEnum Up          = #{const GMP_RNDU} 
-    fromEnum Down        = #{const GMP_RNDD} 
+    fromEnum Near        = #{const GMP_RNDN}
+    fromEnum Zero        = #{const GMP_RNDZ}
+    fromEnum Up          = #{const GMP_RNDU}
+    fromEnum Down        = #{const GMP_RNDD}
     fromEnum MPFR_RNDNA   = #{const GMP_RNDNA}
-    
+
     toEnum #{const GMP_RNDN}    = Near
     toEnum #{const GMP_RNDZ}    = Zero
     toEnum #{const GMP_RNDU}    = Up
     toEnum #{const GMP_RNDD}    = Down
     toEnum (#{const GMP_RNDNA}) = MPFR_RNDNA
 #else
-    fromEnum Near        = #{const MPFR_RNDN} 
-    fromEnum Zero        = #{const MPFR_RNDZ} 
-    fromEnum Up          = #{const MPFR_RNDU} 
-    fromEnum Down        = #{const MPFR_RNDD} 
+    fromEnum Near        = #{const MPFR_RNDN}
+    fromEnum Zero        = #{const MPFR_RNDZ}
+    fromEnum Up          = #{const MPFR_RNDU}
+    fromEnum Down        = #{const MPFR_RNDD}
     fromEnum MPFR_RNDNA   = #{const MPFR_RNDNA}
-    
+
     toEnum #{const MPFR_RNDN}    = Near
     toEnum #{const MPFR_RNDZ}    = Zero
     toEnum #{const MPFR_RNDU}    = Up
     toEnum #{const MPFR_RNDD}    = Down
     toEnum (#{const MPFR_RNDNA}) = MPFR_RNDNA
 #endif
-    toEnum i                    = error $ "RoundMode.toEnum called with illegal argument :" ++ show i 
+    toEnum i                    = error $ "RoundMode.toEnum called with illegal argument :" ++ show i
 
 
 data MPFR = MP { precision :: {-# UNPACK #-} !CPrecision,
                  sign :: {-# UNPACK #-} !Sign,
                  exponent :: {-# UNPACK #-} !Exp,
                  limbs :: {-# UNPACK #-} !(ForeignPtr Limb)
-} deriving (Typeable)
+} deriving (Typeable, Generic)
 
 instance Storable MPFR where
     sizeOf _ = #size __mpfr_struct
     alignment _ = alignment (undefined :: #{type mpfr_prec_t})
     peek = error "MPFR.peek: Not needed and not applicable"
     poke p (MP prec s e fp) = do #{poke __mpfr_struct, _mpfr_prec} p prec
-                                 #{poke __mpfr_struct, _mpfr_sign} p s 
+                                 #{poke __mpfr_struct, _mpfr_sign} p s
                                  #{poke __mpfr_struct, _mpfr_exp} p e
                                  withForeignPtr fp $ \p1 -> #{poke __mpfr_struct, _mpfr_d} p p1
 
@@ -75,16 +76,16 @@
 instance Num Precision where
     (Precision w) + (Precision w') = Precision $ w + w'
     (Precision w) * (Precision w') = Precision $ w * w'
-    (Precision a) - (Precision b) = 
-        if a >= b 
-        then Precision (a - b) 
-        else error $ "instance Precision Num (-): " ++ 
+    (Precision a) - (Precision b) =
+        if a >= b
+        then Precision (a - b)
+        else error $ "instance Precision Num (-): " ++
                        "Operation would result in negative precision."
-    negate = error $ "instance Precision Num negate: " ++ 
+    negate = error $ "instance Precision Num negate: " ++
                        "operation would result in negative precision"
     abs = id
     signum (Precision x) = Precision . signum $ x
-    fromInteger i = if i >= 0 
+    fromInteger i = if i >= 0
                     then Precision . fromInteger $ i
                     else error $ "instance Precision Num fromInteger: " ++
                              "operation would result  in negative precision"
@@ -100,7 +101,7 @@
 peekNoLimbPrec      :: Ptr MPFR -> IO (Sign, Exp)
 peekNoLimbPrec p = do r21 <- #{peek __mpfr_struct, _mpfr_sign} p
                       r22 <- #{peek __mpfr_struct, _mpfr_exp} p
-                      return (r21, r22)            
+                      return (r21, r22)
 
 
 {-# INLINE peekP #-}
@@ -111,12 +112,12 @@
                 return (MP r11 r21 r22 fp)
 {-# INLINE withDummy #-}
 withDummy     :: Precision -> (Ptr MPFR -> IO CInt) -> IO (MPFR, Int)
-withDummy w f = 
+withDummy w f =
     do alloca $ \ptr -> do
                       ls <- mpfr_custom_get_size (fromIntegral . runPrec $ w)
                       fp <- mallocForeignPtrBytes (fromIntegral ls)
                       #{poke __mpfr_struct, _mpfr_prec} ptr (fromIntegral w :: CPrecision)
-                      #{poke __mpfr_struct, _mpfr_sign} ptr (1 :: Sign) 
+                      #{poke __mpfr_struct, _mpfr_sign} ptr (1 :: Sign)
                       #{poke __mpfr_struct, _mpfr_exp} ptr (0 :: Exp)
                       withForeignPtr fp $ \p1 -> #{poke __mpfr_struct, _mpfr_d} ptr p1
                       r2 <- f ptr
@@ -126,11 +127,11 @@
 {-# INLINE pokeDummy #-}
 pokeDummy          :: Ptr MPFR -> ForeignPtr Limb -> Precision -> IO ()
 pokeDummy ptr fp p = do #{poke __mpfr_struct, _mpfr_prec} ptr ((fromIntegral . runPrec $ p) :: CPrecision)
-                        #{poke __mpfr_struct, _mpfr_sign} ptr (0 :: Sign) 
+                        #{poke __mpfr_struct, _mpfr_sign} ptr (0 :: Sign)
                         #{poke __mpfr_struct, _mpfr_exp} ptr (0 :: Exp)
                         withForeignPtr fp $ \p1 -> #{poke __mpfr_struct, _mpfr_d} ptr p1
 
-bitsPerMPLimb :: Int 
+bitsPerMPLimb :: Int
 bitsPerMPLimb = 8 * #size mp_limb_t
 
 bitsPerIntegerLimb :: Int
@@ -172,7 +173,7 @@
 
 --------------------
 foreign import ccall unsafe "mpfr_get_prec_wrap"
-        mpfr_get_prec :: Ptr MPFR -> IO CPrecision 
+        mpfr_get_prec :: Ptr MPFR -> IO CPrecision
 
 ----------------------------------------------------------------
 
@@ -222,10 +223,10 @@
         mpfr_get_d_2exp :: Ptr CLong -> Ptr MPFR -> CRoundMode -> IO CDouble
 
 -- !!!!!!! next 4 set erange flags
-foreign import ccall unsafe "mpfr_get_si" 
+foreign import ccall unsafe "mpfr_get_si"
         mpfr_get_si :: Ptr MPFR -> CRoundMode -> IO CLong
 
-foreign import ccall unsafe "mpfr_get_ui" 
+foreign import ccall unsafe "mpfr_get_ui"
         mpfr_get_ui :: Ptr MPFR -> CRoundMode -> IO CULong
 
 foreign import ccall unsafe "mpfr_get_str"
@@ -278,13 +279,13 @@
 foreign import ccall unsafe "mpfr_sub"
         mpfr_sub :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
-foreign import ccall unsafe "mpfr_ui_sub" 
+foreign import ccall unsafe "mpfr_ui_sub"
         mpfr_ui_sub :: Ptr MPFR -> CULong -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_sub_ui"
         mpfr_sub_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt
 
-foreign import ccall unsafe "mpfr_si_sub" 
+foreign import ccall unsafe "mpfr_si_sub"
         mpfr_si_sub :: Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_sub_si"
@@ -297,7 +298,7 @@
         mpfr_d_sub :: Ptr MPFR -> CDouble -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_mul"
-        mpfr_mul :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 
+        mpfr_mul :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_mul_ui"
         mpfr_mul_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt
@@ -345,10 +346,10 @@
         mpfr_cbrt :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_root"
-        mpfr_root :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt 
+        mpfr_root :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_pow"
-        mpfr_pow :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 
+        mpfr_pow :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_pow_ui"
         mpfr_pow_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt
@@ -363,10 +364,10 @@
         mpfr_ui_pow :: Ptr MPFR -> CULong -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_neg"
-        mpfr_neg :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 
+        mpfr_neg :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_abs_wrap"
-        mpfr_abs :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 
+        mpfr_abs :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_dim"
         mpfr_dim :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
@@ -422,30 +423,30 @@
         mpfr_zero_p :: Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_sgn_wrap"
-        mpfr_sgn :: Ptr MPFR -> IO CInt 
+        mpfr_sgn :: Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_greater_p"
         mpfr_greater_p :: Ptr MPFR ->  Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_greaterequal_p"
-        mpfr_greaterequal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 
+        mpfr_greaterequal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_less_p"
-        mpfr_less_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 
+        mpfr_less_p :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_lessequal_p"
-        mpfr_lessequal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 
+        mpfr_lessequal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_lessgreater_p"
-        mpfr_lessgreater_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 
+        mpfr_lessgreater_p :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_equal_p"
-        mpfr_equal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 
+        mpfr_equal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
 foreign import ccall unsafe "mpfr_unordered_p"
-        mpfr_unordered_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 
+        mpfr_unordered_p :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
--- special functions 
+-- special functions
 
 foreign import ccall unsafe "mpfr_log"
         mpfr_log :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt
@@ -552,6 +553,9 @@
 foreign import ccall unsafe "mpfr_lgamma"
         mpfr_lgamma :: Ptr MPFR -> Ptr CInt -> Ptr MPFR ->  CRoundMode -> IO CInt
 
+foreign import ccall unsafe "mpfr_digamma"
+        mpfr_digamma :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt
+
 foreign import ccall unsafe "mpfr_zeta"
         mpfr_zeta :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt
 
@@ -583,16 +587,16 @@
         mpfr_yn :: Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_fma"
-        mpfr_fma :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt  
+        mpfr_fma :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_fms"
         mpfr_fms :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_agm"
-        mpfr_agm :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt  
+        mpfr_agm :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_hypot"
-        mpfr_hypot :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt  
+        mpfr_hypot :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 -- constants
 foreign import ccall unsafe "mpfr_const_log2_wrap"
@@ -631,7 +635,7 @@
 
 foreign import ccall unsafe "mpfr_trunc_wrap"
         mpfr_trunc :: Ptr MPFR -> Ptr MPFR -> IO CInt
- 
+
 foreign import ccall unsafe "mpfr_rint_ceil"
         mpfr_rint_ceil :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
@@ -653,10 +657,10 @@
 foreign import ccall unsafe "mpfr_fmod"
         mpfr_fmod :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
-foreign import ccall unsafe "mpfr_remainder" 
+foreign import ccall unsafe "mpfr_remainder"
         mpfr_remainder :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
-foreign import ccall unsafe "mpfr_remquo" 
+foreign import ccall unsafe "mpfr_remquo"
         mpfr_remquo :: Ptr MPFR -> Ptr CLong -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_integer_p"
@@ -696,7 +700,7 @@
         mpfr_setsign :: Ptr MPFR -> Ptr MPFR -> CInt -> CRoundMode -> IO CInt
 
 foreign import ccall unsafe "mpfr_copysign_wrap"
-        mpfr_copysign :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 
+        mpfr_copysign :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt
 
 ---------------------------------------------------------------
 -- rounding mode related functions
@@ -781,7 +785,7 @@
 
 ---------------------------------------------------------------
 -- custom interface
-foreign import ccall unsafe "mpfr_custom_get_size_wrap" 
+foreign import ccall unsafe "mpfr_custom_get_size_wrap"
         mpfr_custom_get_size :: CPrecision -> IO #{type size_t}
 
 foreign import ccall unsafe "mpfr_custom_init_wrap"
diff --git a/src/Data/Number/MPFR/Instances/Down.hs b/src/Data/Number/MPFR/Instances/Down.hs
--- a/src/Data/Number/MPFR/Instances/Down.hs
+++ b/src/Data/Number/MPFR/Instances/Down.hs
@@ -10,8 +10,8 @@
     Portability :  non-portable
 
   This module defines instances 'Num', 'Real', 'Fractional', 'Floating' and 'RealFrac' of 'MPFR'.
-  Operations are rounded with 'RoundMode' 'Down' and computed with maximum precision of two 
-  operands or with the precision of the operand. 
+  Operations are rounded with 'RoundMode' 'Down' and computed with maximum precision of two
+  operands or with the precision of the operand.
 -}
 
 
@@ -31,13 +31,13 @@
 
 import Data.Ratio
 
-#ifdef INTEGER_SIMPLE
---import GHC.Integer.Simple.Internals
-#endif
-#ifdef INTEGER_GMP
-import GHC.Integer.GMP.Internals
-import qualified GHC.Exts as E
-#endif
+-- #ifdef INTEGER_SIMPLE
+-- --import GHC.Integer.Simple.Internals
+-- #endif
+-- #ifdef INTEGER_GMP
+-- import GHC.Integer.GMP.Internals
+-- import qualified GHC.Exts as E
+-- #endif
 
 
 instance Num MPFR where
@@ -47,14 +47,16 @@
     negate d      = A.neg Down (getPrec d) d
     abs d         = A.absD Down (getPrec d) d
     signum        = fromInt Down minPrec . fromMaybe (-1) .sgn
-#ifdef INTEGER_SIMPLE
-    fromInteger i = 
+    fromInteger i =
         fromIntegerA Down (max minPrec $ 1 + bitsInInteger i) i
-#endif
-#ifdef INTEGER_GMP
-    fromInteger (S# i) = fromInt Down minPrec (E.I# i)
-    fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i 
-#endif
+-- #ifdef INTEGER_SIMPLE
+--     fromInteger i =
+--         fromIntegerA Down (max minPrec $ 1 + bitsInInteger i) i
+-- #endif
+-- #ifdef INTEGER_GMP
+--     fromInteger (S# i) = fromInt Down minPrec (E.I# i)
+--     fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i
+-- #endif
 
 instance Real MPFR where
     toRational d = n % 2 ^ e
@@ -73,7 +75,7 @@
     pi           = S.pi Down 53
     exp d        = S.exp Down (getPrec d) d
     log d        = S.log Down (getPrec d) d
-    sqrt d       = A.sqrt Down (getPrec d) d 
+    sqrt d       = A.sqrt Down (getPrec d) d
     (**) d d'    = A.pow Down (maxPrec d d') d d'
     logBase d d' = Prelude.log d' / Prelude.log d
     sin d        = S.sin Down (getPrec d) d
@@ -96,3 +98,20 @@
               e = denominator r
               n = quot m e
               f = frac Down (getPrec d) d
+
+instance RealFloat MPFR where
+    floatRadix _ = 2
+    floatDigits = fromInteger . toInteger . getPrec
+    floatRange _ = error "floatRange is not defined for MPFR numbers"
+    decodeFloat x = (d,e)
+      where
+      (d,eE) = decompose x
+      e = fromInteger (toInteger eE)
+    encodeFloat d e =
+      (fromInteger d) / ((fromInteger 2)^e) -- TODO: construct it directly
+    isNaN (MP _ _ e _) = (e == expNaN)
+    isInfinite (MP _ _ e _) = (e == expInf)
+    isDenormalized _ = False
+    isNegativeZero d@(MP _ _ e _) = (e == expZero && signbit d)
+    isIEEE _ = False
+    atan2 d1 d2 = S.atan2 Near (maxPrec d1 d2) d1 d2
diff --git a/src/Data/Number/MPFR/Instances/Near.hs b/src/Data/Number/MPFR/Instances/Near.hs
--- a/src/Data/Number/MPFR/Instances/Near.hs
+++ b/src/Data/Number/MPFR/Instances/Near.hs
@@ -10,7 +10,7 @@
     Portability :  non-portable
 
   This module defines instances 'Num', 'Real', 'Fractional', 'Floating' and 'RealFrac' of 'MPFR'.
-  Operations are rounded with 'RoundMode' 'Near' and computed with maximum precision of two 
+  Operations are rounded with 'RoundMode' 'Near' and computed with maximum precision of two
   operands or with the precision of the operand.
 -}
 
@@ -30,13 +30,13 @@
 
 import Data.Ratio
 
-#ifdef INTEGER_SIMPLE
---import GHC.Integer.Simple.Internals
-#endif
-#ifdef INTEGER_GMP
-import GHC.Integer.GMP.Internals
-import qualified GHC.Exts as E
-#endif
+-- #ifdef INTEGER_SIMPLE
+-- --import GHC.Integer.Simple.Internals
+-- #endif
+-- #ifdef INTEGER_GMP
+-- import GHC.Integer.GMP.Internals
+-- import qualified GHC.Exts as E
+-- #endif
 
 instance Num MPFR where
     d + d'        = A.add Near (maxPrec d d') d d'
@@ -45,14 +45,16 @@
     negate d      = A.neg Near (getPrec d) d
     abs d         = A.absD Near (getPrec d) d
     signum        = fromInt Near minPrec . fromMaybe (-1) . sgn
-#ifdef INTEGER_SIMPLE
-    fromInteger i = 
+    fromInteger i =
         fromIntegerA Near (max minPrec $ 1 + bitsInInteger i) i
-#endif
-#ifdef INTEGER_GMP
-    fromInteger (S# i) = fromInt Near minPrec (E.I# i)
-    fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i 
-#endif
+-- #ifdef INTEGER_SIMPLE
+--     fromInteger i =
+--         fromIntegerA Near (max minPrec $ 1 + bitsInInteger i) i
+-- #endif
+-- #ifdef INTEGER_GMP
+--     fromInteger (S# i) = fromInt Near minPrec (E.I# i)
+--     fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i
+-- #endif
 
 instance Real MPFR where
     toRational d = n % 2 ^ e
@@ -71,7 +73,7 @@
     pi           = S.pi Near 53
     exp d        = S.exp Near (getPrec d) d
     log d        = S.log Near (getPrec d) d
-    sqrt d       = A.sqrt Near (getPrec d) d 
+    sqrt d       = A.sqrt Near (getPrec d) d
     (**) d d'    = A.pow Near (maxPrec d d') d d'
     logBase d d' = Prelude.log d' / Prelude.log d
     sin d        = S.sin Near (getPrec d) d
@@ -94,3 +96,20 @@
               e = denominator r
               n = quot m e
               f = frac Near (getPrec d) d
+
+instance RealFloat MPFR where
+    floatRadix _ = 2
+    floatDigits = fromInteger . toInteger . getPrec
+    floatRange _ = error "floatRange is not defined for MPFR numbers"
+    decodeFloat x = (d,e)
+      where
+      (d,eE) = decompose x
+      e = fromInteger (toInteger eE)
+    encodeFloat d e =
+      (fromInteger d) / ((fromInteger 2)^e) -- TODO: construct it directly
+    isNaN (MP _ _ e _) = (e == expNaN)
+    isInfinite (MP _ _ e _) = (e == expInf)
+    isDenormalized _ = False
+    isNegativeZero d@(MP _ _ e _) = (e == expZero && signbit d)
+    isIEEE _ = False
+    atan2 d1 d2 = S.atan2 Near (maxPrec d1 d2) d1 d2
diff --git a/src/Data/Number/MPFR/Instances/Up.hs b/src/Data/Number/MPFR/Instances/Up.hs
--- a/src/Data/Number/MPFR/Instances/Up.hs
+++ b/src/Data/Number/MPFR/Instances/Up.hs
@@ -11,7 +11,7 @@
     Portability :  non-portable
 
   This module defines instances 'Num', 'Real', 'Fractional', 'Floating' and 'RealFrac' of 'MPFR'.
-  Operations are rounded with 'RoundMode' 'Up' and computed with maximum precision of two 
+  Operations are rounded with 'RoundMode' 'Up' and computed with maximum precision of two
   operands or with the precision of the operand.
 -}
 
@@ -31,13 +31,13 @@
 
 import Data.Ratio
 
-#ifdef INTEGER_SIMPLE
---import GHC.Integer.Simple.Internals
-#endif
-#ifdef INTEGER_GMP
-import GHC.Integer.GMP.Internals
-import qualified GHC.Exts as E
-#endif
+-- #ifdef INTEGER_SIMPLE
+-- --import GHC.Integer.Simple.Internals
+-- #endif
+-- #ifdef INTEGER_GMP
+-- import GHC.Integer.GMP.Internals
+-- import qualified GHC.Exts as E
+-- #endif
 
 
 instance Num MPFR where
@@ -47,14 +47,16 @@
     negate d      = A.neg Up (getPrec d) d
     abs d         = A.absD Up (getPrec d) d
     signum        = fromInt Up minPrec . fromMaybe (-1) . sgn
-#ifdef INTEGER_SIMPLE
-    fromInteger i = 
+    fromInteger i =
         fromIntegerA Up (max minPrec $ 1 + bitsInInteger i) i
-#endif
-#ifdef INTEGER_GMP
-    fromInteger (S# i) = fromInt Up minPrec (E.I# i)
-    fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i 
-#endif
+-- #ifdef INTEGER_SIMPLE
+--     fromInteger i =
+--         fromIntegerA Up (max minPrec $ 1 + bitsInInteger i) i
+-- #endif
+-- #ifdef INTEGER_GMP
+--     fromInteger (S# i) = fromInt Up minPrec (E.I# i)
+--     fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i
+-- #endif
 
 instance Real MPFR where
     toRational d = n % 2 ^ e
@@ -73,7 +75,7 @@
     pi           = S.pi Up 53
     exp d        = S.exp Up (getPrec d) d
     log d        = S.log Up (getPrec d) d
-    sqrt d       = A.sqrt Up (getPrec d) d 
+    sqrt d       = A.sqrt Up (getPrec d) d
     (**) d d'    = A.pow Up (maxPrec d d') d d'
     logBase d d' = Prelude.log d' / Prelude.log d
     sin d        = S.sin Up (getPrec d) d
@@ -96,3 +98,20 @@
               e = denominator r
               n = quot m e
               f = frac Up (getPrec d) d
+
+instance RealFloat MPFR where
+    floatRadix _ = 2
+    floatDigits = fromInteger . toInteger . getPrec
+    floatRange _ = error "floatRange is not defined for MPFR numbers"
+    decodeFloat x = (d,e)
+      where
+      (d,eE) = decompose x
+      e = fromInteger (toInteger eE)
+    encodeFloat d e =
+      (fromInteger d) / ((fromInteger 2)^e) -- TODO: construct it directly
+    isNaN (MP _ _ e _) = (e == expNaN)
+    isInfinite (MP _ _ e _) = (e == expInf)
+    isDenormalized _ = False
+    isNegativeZero d@(MP _ _ e _) = (e == expZero && signbit d)
+    isIEEE _ = False
+    atan2 d1 d2 = S.atan2 Near (maxPrec d1 d2) d1 d2
diff --git a/src/Data/Number/MPFR/Instances/Zero.hs b/src/Data/Number/MPFR/Instances/Zero.hs
--- a/src/Data/Number/MPFR/Instances/Zero.hs
+++ b/src/Data/Number/MPFR/Instances/Zero.hs
@@ -10,7 +10,7 @@
     Portability :  non-portable
 
   This module defines instances 'Num', 'Real', 'Fractional', 'Floating' and 'RealFrac' of 'MPFR'.
-  Operations are rounded with 'RoundMode' 'Zero' and computed with maximum precision of two 
+  Operations are rounded with 'RoundMode' 'Zero' and computed with maximum precision of two
   operands or with the precision of the operand.
 -}
 
@@ -31,13 +31,13 @@
 
 import Data.Ratio
 
-#ifdef INTEGER_SIMPLE
---import GHC.Integer.Simple.Internals
-#endif
-#ifdef INTEGER_GMP
-import GHC.Integer.GMP.Internals
-import qualified GHC.Exts as E
-#endif
+-- #ifdef INTEGER_SIMPLE
+-- --import GHC.Integer.Simple.Internals
+-- #endif
+-- #ifdef INTEGER_GMP
+-- import GHC.Integer.GMP.Internals
+-- import qualified GHC.Exts as E
+-- #endif
 
 instance Num MPFR where
     d + d'        = A.add Zero (maxPrec d d') d d'
@@ -46,14 +46,16 @@
     negate d      = A.neg Zero (getPrec d) d
     abs d         = A.absD Zero (getPrec d) d
     signum        = fromInt Zero minPrec . fromMaybe (-1) . sgn
-#ifdef INTEGER_SIMPLE
-    fromInteger i = 
+    fromInteger i =
         fromIntegerA Zero (max minPrec $ 1 + bitsInInteger i) i
-#endif
-#ifdef INTEGER_GMP
-    fromInteger (S# i) = fromInt Zero minPrec (E.I# i)
-    fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i 
-#endif
+-- #ifdef INTEGER_SIMPLE
+--     fromInteger i =
+--         fromIntegerA Zero (max minPrec $ 1 + bitsInInteger i) i
+-- #endif
+-- #ifdef INTEGER_GMP
+--     fromInteger (S# i) = fromInt Zero minPrec (E.I# i)
+--     fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i
+-- #endif
 
 instance Real MPFR where
     toRational d = n % 2 ^ e
@@ -72,7 +74,7 @@
     pi           = S.pi Zero 53
     exp d        = S.exp Zero (getPrec d) d
     log d        = S.log Zero (getPrec d) d
-    sqrt d       = A.sqrt Zero (getPrec d) d 
+    sqrt d       = A.sqrt Zero (getPrec d) d
     (**) d d'    = A.pow Zero (maxPrec d d') d d'
     logBase d d' = Prelude.log d' / Prelude.log d
     sin d        = S.sin Zero (getPrec d) d
@@ -95,3 +97,20 @@
               e = denominator r
               n = quot m e
               f = frac Zero (getPrec d) d
+
+instance RealFloat MPFR where
+    floatRadix _ = 2
+    floatDigits = fromInteger . toInteger . getPrec
+    floatRange _ = error "floatRange is not defined for MPFR numbers"
+    decodeFloat x = (d,e)
+      where
+      (d,eE) = decompose x
+      e = fromInteger (toInteger eE)
+    encodeFloat d e =
+      (fromInteger d) / ((fromInteger 2)^e) -- TODO: construct it directly
+    isNaN (MP _ _ e _) = (e == expNaN)
+    isInfinite (MP _ _ e _) = (e == expInf)
+    isDenormalized _ = False
+    isNegativeZero d@(MP _ _ e _) = (e == expZero && signbit d)
+    isIEEE _ = False
+    atan2 d1 d2 = S.atan2 Near (maxPrec d1 d2) d1 d2
diff --git a/src/Data/Number/MPFR/Internal.hs b/src/Data/Number/MPFR/Internal.hs
--- a/src/Data/Number/MPFR/Internal.hs
+++ b/src/Data/Number/MPFR/Internal.hs
@@ -1,10 +1,10 @@
 {-# LANGUAGE BangPatterns #-}
 
 module Data.Number.MPFR.Internal (
-       module Data.Number.MPFR.FFIhelper, 
+       module Data.Number.MPFR.FFIhelper,
        withMPFRsBA, withMPFRBAui, withMPFRBAiu, withMPFRBAd,
-       withMPFRBAsi, withMPFRBAis,  withMPFRBAd', 
-       withMPFRB, withMPFRP, withMPFR, withMPFRBB, withMPFRC, 
+       withMPFRBAsi, withMPFRBAis,  withMPFRBAd',
+       withMPFRB, withMPFRP, withMPFR, withMPFRBB, withMPFRC,
        withMPFRF, withMPFRUI, withMPFRR, checkPrec, getMantissa',
        unsafePerformIO, peek, Ptr, nullPtr, mallocForeignPtrBytes, with,
        withForeignPtr, CInt, CLong, CULong, withCString, peekCString, alloca,
@@ -22,7 +22,7 @@
 
 import Data.Bits(shiftL)
 
-import Data.Word(Word)
+-- import Data.Word(Word)
 
 -- these are helper functions, only for internal use
 {-# INLINE withMPFRsBA #-}
@@ -30,98 +30,98 @@
                                -> (Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt)
                                -> (MPFR, Int)
 withMPFRsBA r p !mp1 !mp2 f = unsafePerformIO go
-    where go = withDummy p $ \p1 -> 
-               with mp1 $ \p2 -> 
-               with mp2 $ \p3 -> 
+    where go = withDummy p $ \p1 ->
+               with mp1 $ \p2 ->
+               with mp2 $ \p3 ->
                f p1 p2 p3 ((fromIntegral . fromEnum) r)
-                          
 
+
 {-# INLINE withMPFRBAui #-}
 withMPFRBAui :: RoundMode -> Precision -> MPFR -> CULong
                   ->  (Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt)
-                  -> (MPFR, Int) 
+                  -> (MPFR, Int)
 withMPFRBAui r p !mp1 d f = unsafePerformIO go
-    where go = withDummy p $ \p1 -> 
-               with mp1 $ \p2 -> 
+    where go = withDummy p $ \p1 ->
+               with mp1 $ \p2 ->
                f p1 p2 d ((fromIntegral . fromEnum) r)
-                                
+
 {-# INLINE withMPFRBAsi #-}
 withMPFRBAsi             :: RoundMode -> Precision -> MPFR -> CLong
                               -> (Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt)
                               -> (MPFR, Int)
-withMPFRBAsi r p !mp1 d f = unsafePerformIO go 
-    where go = withDummy p $ \ p1 -> 
-               with mp1 $ \ p2 -> 
+withMPFRBAsi r p !mp1 d f = unsafePerformIO go
+    where go = withDummy p $ \ p1 ->
+               with mp1 $ \ p2 ->
                f p1 p2 d ((fromIntegral . fromEnum) r)
-                                  
+
 {-# INLINE withMPFRBAiu #-}
 withMPFRBAiu             :: RoundMode -> Precision -> CULong -> MPFR
                               -> (Ptr MPFR -> CULong -> Ptr MPFR -> CRoundMode -> IO CInt)
-                              -> (MPFR, Int) 
-withMPFRBAiu r p d !mp1 f = unsafePerformIO go 
-    where go = withDummy p $ \p1 -> 
-               with mp1 $ \p2 -> 
+                              -> (MPFR, Int)
+withMPFRBAiu r p d !mp1 f = unsafePerformIO go
+    where go = withDummy p $ \p1 ->
+               with mp1 $ \p2 ->
                f p1 d p2 ((fromIntegral . fromEnum) r)
-                     
+
 {-# INLINE withMPFRBAis #-}
 withMPFRBAis             :: RoundMode -> Precision -> CLong -> MPFR
                               -> (Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt)
-                              -> (MPFR, Int) 
+                              -> (MPFR, Int)
 withMPFRBAis r p d !mp1 f = unsafePerformIO go
     where go = withDummy p $ \p1 ->
-               with mp1 $ \p2 -> 
+               with mp1 $ \p2 ->
                f p1 d p2 ((fromIntegral . fromEnum) r)
 {-# INLINE withMPFRBAd #-}
 withMPFRBAd              :: RoundMode -> Precision -> MPFR -> CDouble
                                -> (Ptr MPFR -> Ptr MPFR -> CDouble -> CRoundMode -> IO CInt)
                                -> (MPFR, Int)
-withMPFRBAd r p !mp1 d f = unsafePerformIO go 
+withMPFRBAd r p !mp1 d f = unsafePerformIO go
     where go = withDummy p $ \ p1 ->
                with mp1 $ \ p2 ->
                f p1 p2 d ((fromIntegral . fromEnum) r)
-                                  
+
 {-# INLINE withMPFRBAd' #-}
 withMPFRBAd'              :: RoundMode -> Precision -> CDouble -> MPFR
                                -> (Ptr MPFR -> CDouble -> Ptr MPFR -> CRoundMode -> IO CInt)
-                               -> (MPFR, Int) 
-withMPFRBAd' r p d !mp1 f = unsafePerformIO go 
+                               -> (MPFR, Int)
+withMPFRBAd' r p d !mp1 f = unsafePerformIO go
     where go = withDummy p $ \p1 ->
                with mp1 $ \p2 ->
                f p1 d p2 ((fromIntegral . fromEnum) r)
 
-                     
+
 {-# INLINE withMPFRB #-}
-withMPFRB       :: MPFR -> (Ptr MPFR -> IO CInt) -> CInt 
+withMPFRB       :: MPFR -> (Ptr MPFR -> IO CInt) -> CInt
 withMPFRB !mp1 f = unsafePerformIO go
     where go = with mp1 f
 
-withMPFRP       :: MPFR -> (Ptr MPFR -> IO CPrecision) -> CPrecision 
+withMPFRP       :: MPFR -> (Ptr MPFR -> IO CPrecision) -> CPrecision
 withMPFRP !mp1 f = unsafePerformIO go
     where go = with mp1 f
 
 {-# INLINE withMPFR #-}
-withMPFR           :: RoundMode -> Precision -> MPFR 
-                        -> (Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt) 
+withMPFR           :: RoundMode -> Precision -> MPFR
+                        -> (Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt)
                         -> (MPFR, Int)
-withMPFR r p !mp1 f = unsafePerformIO go 
+withMPFR r p !mp1 f = unsafePerformIO go
     where go = withDummy p $ \p1 ->
                with mp1 $ \p2 ->
                f p1 p2 ((fromIntegral . fromEnum) r)
-                      
+
 {-# INLINE withMPFRBB #-}
-withMPFRBB           :: MPFR -> MPFR 
-                          -> (Ptr MPFR -> Ptr MPFR -> IO CInt) 
-                          -> CInt  
+withMPFRBB           :: MPFR -> MPFR
+                          -> (Ptr MPFR -> Ptr MPFR -> IO CInt)
+                          -> CInt
 withMPFRBB !mp1 !mp2 f = unsafePerformIO go
     where go = with mp1 $ with mp2 . f
-                              
+
 {-# INLINE withMPFRC #-}
 withMPFRC       :: RoundMode -> Precision ->
                      (Ptr MPFR -> CRoundMode -> IO CInt) -> (MPFR, Int)
 withMPFRC r p f = unsafePerformIO go
     where go = withDummy p $ \p1 ->
                f p1 ((fromIntegral . fromEnum) r)
-   
+
 withMPFRF         :: MPFR -> RoundMode
                        -> (Ptr MPFR -> CRoundMode -> IO CInt)
                        -> Int
@@ -132,10 +132,10 @@
 withMPFRUI         :: RoundMode -> Precision -> Word
                         -> (Ptr MPFR -> CULong -> CRoundMode -> IO CInt)
                         -> (MPFR, Int)
-withMPFRUI r p d f = unsafePerformIO go 
+withMPFRUI r p d f = unsafePerformIO go
     where go = withDummy p $ \p1 ->
                f p1 (fromIntegral d) ((fromIntegral . fromEnum) r)
-                    
+
 {-# INLINE withMPFRR #-}
 withMPFRR       :: Precision -> MPFR
                      -> (Ptr MPFR -> Ptr MPFR -> IO CInt)
@@ -143,14 +143,14 @@
 withMPFRR p !d f = unsafePerformIO go
     where go = withDummy p $ with d . f
 
-                        
+
 {-# INLINE checkPrec #-}
 checkPrec :: Precision -> Precision
 checkPrec = max minPrec
 
 getMantissa'     :: MPFR -> [Limb]
 getMantissa' (MP p _ _ p1) = unsafePerformIO go
-    where go = withForeignPtr p1 $ 
+    where go = withForeignPtr p1 $
                peekArray (Prelude.ceiling ((fromIntegral p ::Double) / fromIntegral bitsPerMPLimb))
 
 minPrec :: Precision
diff --git a/src/Data/Number/MPFR/Mutable/Arithmetic.hs b/src/Data/Number/MPFR/Mutable/Arithmetic.hs
--- a/src/Data/Number/MPFR/Mutable/Arithmetic.hs
+++ b/src/Data/Number/MPFR/Mutable/Arithmetic.hs
@@ -20,7 +20,7 @@
 
 import Control.Monad.ST(ST)
 
-import Data.Word(Word)
+-- import Data.Word(Word)
 
 add :: MMPFR s -> MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 add = withMutableMPFRBA mpfr_add
@@ -65,11 +65,11 @@
 muli = withMutableMPFR1 mpfr_mul_si
 
 muld :: MMPFR s -> MMPFR s -> Double -> RoundMode -> ST s Int
-muld = withMutableMPFRd mpfr_mul_d 
-     
+muld = withMutableMPFRd mpfr_mul_d
+
 sqr ::  MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 sqr = withMutableMPFRS mpfr_sqr
-      
+
 div :: MMPFR s -> MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 div = withMutableMPFRBA mpfr_div
 
@@ -93,19 +93,19 @@
 
 sqrt ::  MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 sqrt = withMutableMPFRS mpfr_sqrt
-      
+
 sqrtw :: MMPFR s -> Word -> RoundMode -> ST s Int
 sqrtw = withMutableMPFRUI mpfr_sqrt_ui
 
 recSqrt ::  MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 recSqrt = withMutableMPFRS mpfr_rec_sqrt
- 
+
 cbrt ::  MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 cbrt = withMutableMPFRS mpfr_cbrt
-      
+
 root :: MMPFR s -> MMPFR s -> Word -> RoundMode -> ST s Int
 root = withMutableMPFR1 mpfr_root
-      
+
 pow :: MMPFR s -> MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 pow = withMutableMPFRBA mpfr_pow
 
@@ -118,9 +118,9 @@
 wpow :: MMPFR s -> Word -> MMPFR s -> RoundMode -> ST s Int
 wpow = withMutableMPFR2 mpfr_ui_pow
 
---wpoww       :: RoundMode -> Precision -> Word -> Word -> MPFR 
+--wpoww       :: RoundMode -> Precision -> Word -> Word -> MPFR
 --wpoww r p d = fst . wpoww_ r p d
-   
+
 neg ::  MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 neg = withMutableMPFRS mpfr_neg
 
@@ -141,4 +141,3 @@
 
 div2i :: MMPFR s -> MMPFR s -> Int -> RoundMode -> ST s Int
 div2i = withMutableMPFR1 mpfr_div_2si
-      
diff --git a/src/Data/Number/MPFR/Mutable/Special.hs b/src/Data/Number/MPFR/Mutable/Special.hs
--- a/src/Data/Number/MPFR/Mutable/Special.hs
+++ b/src/Data/Number/MPFR/Mutable/Special.hs
@@ -18,7 +18,7 @@
 
 import Control.Monad.ST(ST)
 
-import Data.Word(Word)
+-- import Data.Word(Word)
 
 log :: MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 log = withMutableMPFRS mpfr_log
@@ -124,9 +124,12 @@
 
 {- TODO
 lgamma       :: RoundMode -> Precision -> MPFR -> (MPFR, Int)
-lgamma r p d = case lgamma_ r p d of 
+lgamma r p d = case lgamma_ r p d of
                  (a, b, _) -> (a,b)
 -}
+
+digamma :: MMPFR s -> MMPFR s -> RoundMode -> ST s Int
+digamma = withMutableMPFRS mpfr_digamma
 
 zeta :: MMPFR s -> MMPFR s -> RoundMode -> ST s Int
 zeta = withMutableMPFRS mpfr_zeta
diff --git a/src/Data/Number/MPFR/Special.hs b/src/Data/Number/MPFR/Special.hs
--- a/src/Data/Number/MPFR/Special.hs
+++ b/src/Data/Number/MPFR/Special.hs
@@ -54,7 +54,7 @@
 
 sincos          :: RoundMode
                 -> Precision -- ^ precision to compute sin
-                -> Precision -- ^ precision to compute cos 
+                -> Precision -- ^ precision to compute cos
                 -> MPFR
                 -> (MPFR, MPFR) -- ^ return (sin x, cos x)
 sincos r p p' d = case sincos_ r p p' d of
@@ -83,7 +83,7 @@
 
 sinhcosh          :: RoundMode
                   -> Precision -- ^ precision to compute sin
-                  -> Precision -- ^ precision to compute cos 
+                  -> Precision -- ^ precision to compute cos
                   -> MPFR
                   -> (MPFR, MPFR) -- ^ return (sin x, cos x)
 sinhcosh r p p' d = case sinhcosh_ r p p' d of
@@ -129,9 +129,12 @@
 lngamma r p = fst . lngamma_ r p
 
 lgamma       :: RoundMode -> Precision -> MPFR -> (MPFR, Int)
-lgamma r p d = case lgamma_ r p d of 
+lgamma r p d = case lgamma_ r p d of
                  (a, b, _) -> (a,b)
 
+digamma     :: RoundMode -> Precision -> MPFR -> MPFR
+digamma r p = fst . digamma_ r p
+
 zeta     :: RoundMode -> Precision -> MPFR -> MPFR
 zeta r p = fst . zeta_ r p
 
@@ -226,17 +229,17 @@
 
 sincos_ :: RoundMode
          -> Precision -- ^ precision to compute sin
-         -> Precision -- ^ precision to compute cos 
+         -> Precision -- ^ precision to compute cos
          -> MPFR
          -> (MPFR, MPFR, Int)
-sincos_ r p p' d = unsafePerformIO go 
+sincos_ r p p' d = unsafePerformIO go
     where go = do ls <- mpfr_custom_get_size (fromIntegral p)
                   fp <- mallocForeignPtrBytes (fromIntegral ls)
                   ls' <- mpfr_custom_get_size (fromIntegral p')
                   fp' <- mallocForeignPtrBytes (fromIntegral ls')
-                  alloca $ \p1 -> do 
+                  alloca $ \p1 -> do
                     pokeDummy p1 fp (fromIntegral ls)
-                    alloca $ \p2 -> do 
+                    alloca $ \p2 -> do
                       pokeDummy p2 fp' (fromIntegral ls')
                       with d $ \p3 -> do
                         r3 <- mpfr_sin_cos p1 p2 p3 ((fromIntegral . fromEnum) r)
@@ -254,7 +257,7 @@
 atan_ r p d = withMPFR r p d mpfr_atan
 
 atan2_ :: RoundMode -> Precision -> MPFR -> MPFR -> (MPFR, Int)
-atan2_ r p d d' = withMPFRsBA r p d d' mpfr_atan2 
+atan2_ r p d d' = withMPFRsBA r p d d' mpfr_atan2
 
 sinh_       :: RoundMode -> Precision -> MPFR -> (MPFR, Int)
 sinh_ r p d = withMPFR r p d mpfr_sinh
@@ -267,17 +270,17 @@
 
 sinhcosh_          :: RoundMode
                    -> Precision -- ^ precision to compute sinh
-                   -> Precision -- ^ precision to compute cosh 
+                   -> Precision -- ^ precision to compute cosh
                    -> MPFR
                    -> (MPFR, MPFR, Int)
-sinhcosh_ r p p' d = unsafePerformIO go 
+sinhcosh_ r p p' d = unsafePerformIO go
     where go = do ls <- mpfr_custom_get_size (fromIntegral p)
                   fp <- mallocForeignPtrBytes (fromIntegral ls)
                   ls' <- mpfr_custom_get_size (fromIntegral p')
                   fp' <- mallocForeignPtrBytes (fromIntegral ls')
-                  alloca $ \p1 -> do 
+                  alloca $ \p1 -> do
                     pokeDummy p1 fp (fromIntegral ls)
-                    alloca $ \p2 -> do 
+                    alloca $ \p2 -> do
                       pokeDummy p2 fp' (fromIntegral ls')
                       with d $ \p3 -> do
                         r3 <- mpfr_sinh_cosh p1 p2 p3 ((fromIntegral . fromEnum) r)
@@ -336,7 +339,10 @@
                         r2 <- peek p3
                         r1 <- peekP p1 fp
                         return (r1, fromIntegral r2, fromIntegral r3)
-                    
+
+digamma_       :: RoundMode -> Precision -> MPFR -> (MPFR, Int)
+digamma_ r p d = withMPFR r p d mpfr_digamma
+
 zeta_       :: RoundMode -> Precision -> MPFR -> (MPFR, Int)
 zeta_ r p d = withMPFR r p d mpfr_zeta
 
@@ -369,19 +375,19 @@
 
 fma_                 :: RoundMode -> Precision -> MPFR -> MPFR -> MPFR -> (MPFR, Int)
 fma_ r p mp1 mp2 mp3 = unsafePerformIO go
-    where go = withDummy p $ \p1 -> 
-                 with mp1 $ \p2 -> 
+    where go = withDummy p $ \p1 ->
+                 with mp1 $ \p2 ->
                    with mp2 $ \p3 ->
                      with mp3 $ \p4 ->
-                       mpfr_fma p1 p2 p3 p4 ((fromIntegral . fromEnum) r) 
+                       mpfr_fma p1 p2 p3 p4 ((fromIntegral . fromEnum) r)
 
 fms_                 :: RoundMode -> Precision -> MPFR -> MPFR -> MPFR -> (MPFR, Int)
 fms_ r p mp1 mp2 mp3 = unsafePerformIO go
     where go = withDummy p $ \p1 ->
-                 with mp1 $ \p2 -> 
+                 with mp1 $ \p2 ->
                    with mp2 $ \p3 ->
                      with mp3 $ \p4 ->
-                       mpfr_fms p1 p2 p3 p4 ((fromIntegral . fromEnum) r) 
+                       mpfr_fms p1 p2 p3 p4 ((fromIntegral . fromEnum) r)
 
 agm_           :: RoundMode -> Precision -> MPFR -> MPFR -> (MPFR,Int)
 agm_ r p d1 d2 =  withMPFRsBA r p d1 d2 mpfr_agm
