diff --git a/IsNull.cabal b/IsNull.cabal
--- a/IsNull.cabal
+++ b/IsNull.cabal
@@ -1,5 +1,5 @@
 name:                IsNull
-version:             0.3.0.0
+version:             0.4.0.0
 synopsis:            A typeclass to determine if a given value is null.
 description:         A typeclass to determine if a given foldable type
                      (or other) is empty ~ null ~ invalid.
@@ -8,7 +8,8 @@
 homepage:            https://github.com/jcristovao/IsNull
 license:             BSD3
 license-file:        LICENSE
-author:              João Cristóvão
+author:              João Cristóvão <jmacristovao@gmail.com>
+                   , Ivan Miljenovic <Ivan.Miljenovic@gmail.com>
 maintainer:          jmacristovao@gmail.com
 category:            Data
 build-type:          Simple
@@ -19,17 +20,18 @@
 cabal-version:       >=1.16
 
 library
-  other-modules:       Data.IsNull.Internal
-  exposed-modules:     Data.IsNull
-  build-depends:       base             >= 4.5    && < 4.8
-                     , base-compat      >= 0.5    && < 0.6
-                     , containers       >= 0.5    && < 0.6
-                     , text             >= 0.11.3 && < 1.3
-                     , bytestring       >= 0.10.0 && < 1.0
-
   hs-source-dirs:      src
   ghc-options:         -Wall
   default-language:    Haskell2010
+  exposed-modules:    Data.IsNull
+  build-depends:      base             >= 4.5    && < 4.8
+                    , containers       >= 0.5    && < 0.6
+                    , text             >= 0.11.3 && < 1.3
+                    , bytestring       >= 0.10.0 && < 1.0
+  if impl(ghc < 7.7)
+    build-depends:
+                      base-compat      >= 0.5    && < 0.6
+
   
 -- the test suite checks for most (modern) applicable types
 -- found on Cabal. Exceptions: utf8-string, ListLike, IxSet
@@ -38,8 +40,8 @@
   type:               exitcode-stdio-1.0
   main-is:            main.hs
   hs-source-dirs:     test,src
+  default-language: Haskell2010
   build-depends:       base             >= 4.5    && < 4.8
-                     , base-compat      >= 0.5    && < 0.6
                      , containers       >= 0.5    && < 0.6
                      , text             >= 0.11.3 && < 1.3
                      , unordered-containers >= 0.2.3
@@ -51,7 +53,11 @@
                      , quickcheck-instances >= 0.3.5 
                      , HUnit            >= 1.2.5.2
                      , hspec            >= 1.7.2
-  default-language: Haskell2010
+  if impl(ghc < 7.7)
+    build-depends:
+                      base-compat      >= 0.5    && < 0.6
+
+
 
 source-repository head
   type:     git
diff --git a/src/Data/IsNull.hs b/src/Data/IsNull.hs
--- a/src/Data/IsNull.hs
+++ b/src/Data/IsNull.hs
@@ -1,12 +1,11 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleInstances  #-}
 {-# LANGUAGE FlexibleContexts   #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE IncoherentInstances  #-}
+{-# LANGUAGE OverlappingInstances #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 {- |
-Module:      IsNull
+Module:      Data.IsNull
 Description: A typeclass to determine if a given value is null.
 Copyright:   João Cristóvão, 2014
 License:     BSD3
@@ -35,8 +34,8 @@
   is provided for the @'Monoid'@ class. It's up to you to use
   @(==) mempty@ instead.
 
-The main use case for this package are boolean conditions,
-namely the @if@ @then@ @else@ construct.
+This class is suitable for use with @GeneralizedNewtypeDeriving@,
+thanks to the precious help of Ivan Miljenovic.
 
 Bugs, suggestions and comments are most welcomed!
 
@@ -44,10 +43,109 @@
 
 -}
 module Data.IsNull (
-    IsNull(..)
+      IsNull(..)
+    , notNull
+    , isNullN
+    , notNullN
+    , isNullM
+    , isNullNM
+    , (<\>)
 ) where
 
+#if !MIN_VERSION_base(4,7,0)
+import qualified Data.Foldable.Compat as F
+#else
+import qualified Data.Foldable        as F
+#endif
+import qualified Data.Text            as T
+import qualified Data.Text.Lazy       as LT
+import qualified Data.ByteString      as BS
+import qualified Data.ByteString.Lazy as LBS
+import qualified Data.IntSet          as IS
 
-import Data.IsNull.Internal
+-- $setup
+-- The code examples in this module require GHC's `OverloadedStrings`
+-- extension:
+--
+-- >>> :set -XOverloadedStrings
+
+class IsNull a where
+  -- | isNull ~ isEmpty ~ isInvalid?
+  --
+  -- >>> isNull (Left 5)
+  -- True
+  --
+  -- >>> isNull ("abc" :: T.Text)
+  -- False
+  --
+  -- >>> isNull [""] -- see isNullN
+  -- False
+  isNull:: a -> Bool
+
+-- | the logical negation of @'isNull'@
+notNull :: (IsNull a) => a -> Bool
+notNull = not . isNull
+
+-- | Nested isNull
+--
+-- >>> isNullN (Just "abc")
+-- False
+--
+-- >>> isNullN (Just "")
+-- True
+--
+-- >>> isNullN (Nothing :: Maybe String)
+-- True
+isNullN :: (IsNull a, F.Foldable f) => f a -> Bool
+isNullN = F.all isNull
+
+-- | Nested isNotNull
+notNullN :: (IsNull a, F.Foldable f) => f a -> Bool
+notNullN = not . isNullN
+
+-- | Monadic isNull
+--
+-- >>> isNullM [""]
+-- [True]
+isNullM :: (IsNull a, Functor m) => m a -> m Bool
+isNullM = fmap isNull
+
+-- | Monadic Nested isNull
+isNullNM :: (IsNull a, Functor m, F.Foldable f) => m (f a) -> m Bool
+isNullNM = fmap isNullN
+
+-- | @'Alternative'@'s @'<|>'@ operator does not always operate as choice,
+-- at least not in an intuitive way (for example with lists).
+-- This one does:
+--
+-- >>> [2,3] <\> [4,5]
+-- [2,3]
+--
+-- >>> [] <\> [4,5]
+-- [4,5]
+--
+-- >>> [] <\> []
+-- []
+(<\>) :: (IsNull a) => a -> a -> a
+(<\>) a b = if isNull a then b else a
+infixl 3 <\>
+
+instance IsNull T.Text where
+  isNull = T.null
+
+instance IsNull LT.Text where
+  isNull = LT.null
+
+instance IsNull BS.ByteString where
+  isNull = BS.null
+
+instance IsNull LBS.ByteString where
+  isNull = LBS.null
+
+instance IsNull IS.IntSet where
+  isNull = IS.null
+
+instance F.Foldable f => IsNull (f a) where
+  isNull = F.foldr (\_ _ -> False) True
 
 
diff --git a/src/Data/IsNull/Internal.hs b/src/Data/IsNull/Internal.hs
deleted file mode 100644
--- a/src/Data/IsNull/Internal.hs
+++ /dev/null
@@ -1,102 +0,0 @@
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE FlexibleContexts     #-}
-{-# LANGUAGE OverloadedStrings    #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-
-module Data.IsNull.Internal where
-
-import qualified Data.Foldable.Compat as F
-import qualified Data.Text            as T
-import qualified Data.Text.Lazy       as LT
-import qualified Data.ByteString      as BS
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.IntSet          as IS
-import Control.Monad (liftM)
-
-
-class IsNull a where
-  -- | isNull ~ isEmpty ~ isInvalid?
-  --
-  -- >>> isNull (Left 5)
-  -- True
-  --
-  -- >>> isNull ("abc" :: T.Text)
-  -- False
-  --
-  -- >>> isNull [""] -- see isNullN
-  -- False
-  isNull:: a -> Bool
-
-  -- | Typing causes arthritis. Alias for @'isNull'@.
-  isN :: a -> Bool
-  isN = isNull
-
-  -- | the logical negation of @'isNull'@
-  notNull :: a -> Bool
-  notNull = not . isNull
-
-  -- | Nested isNull
-  --
-  -- >>> isNullN (Just "abc")
-  -- False
-  --
-  -- >>> isNullN (Just "")
-  -- True
-  --
-  -- >>> isNullN (Nothing :: Maybe String)
-  -- True
-  isNullN :: F.Foldable f => f a -> Bool
-  isNullN = F.all isNull
-
-  -- | Nested isNotNull
-  notNullN :: F.Foldable f => f a -> Bool
-  notNullN = not . isNullN
-
-  -- | Monadic isNull
-  --
-  -- >>> isNullM [""]
-  -- [True]
-  isNullM :: Monad m => m a -> m Bool
-  isNullM = liftM isNull
-
-  -- | Monadic Nested isNull
-  isNullNM :: (Monad m, F.Foldable f) => m (f a) -> m Bool
-  isNullNM = liftM isNullN
-
-  -- | @'Alternative'@'s @'<|>'@ operator does not always operate as choice,
-  -- at least not in an intuitive way (for example with lists).
-  -- This one does:
-  --
-  -- >>> [2,3] <\> [4,5]
-  -- [2,3]
-  --
-  -- >>> [] <\> [4,5]
-  -- [4,5]
-  --
-  -- >>> [] <\> []
-  -- []
-  (<\>) :: a -> a -> a
-  (<\>) a b = if isNull a then b else a
-  infixl 3 <\>
-
-instance IsNull Bool where
-  isNull = not
-
-instance IsNull T.Text where
-  isNull = T.null
-
-instance IsNull LT.Text where
-  isNull = LT.null
-
-instance IsNull BS.ByteString where
-  isNull = BS.null
-
-instance IsNull LBS.ByteString where
-  isNull = LBS.null
-
-instance IsNull IS.IntSet where
-  isNull = IS.null
-
-instance F.Foldable f => IsNull (f a) where
-  isNull = F.foldr (\_ _ -> False) True
-
