diff --git a/Data/IntMultiSet.hs b/Data/IntMultiSet.hs
--- a/Data/IntMultiSet.hs
+++ b/Data/IntMultiSet.hs
@@ -130,7 +130,11 @@
             , showTreeWith
             ) where
 
-import Prelude hiding (filter,foldr,null,map,concatMap)
+import Prelude hiding (filter,foldr,null,map,concatMap
+#if __GLASGOW_HASKELL__ >= 709
+  ,join
+#endif
+  )
 import Data.Monoid (Monoid(..))
 import Data.Typeable ()
 import Data.IntMap.Strict (IntMap)
@@ -356,18 +360,18 @@
 deleteFindMax set = (findMax set, deleteMax set)
 
 -- | /O(log n)/. Retrieves the minimal element of the multiset, and the set stripped from that element
--- @fail@s (in the monad) when passed an empty multiset.
-minView :: Monad m => IntMultiSet -> m (Key, IntMultiSet)
+-- Returns @Nothing@ when passed an empty multiset.
+minView :: IntMultiSet -> Maybe (Key, IntMultiSet)
 minView x
-  | null x    = fail "IntMultiSet.minView: empty multiset"
-  | otherwise = return (deleteFindMin x)
+  | null x    = Nothing
+  | otherwise = Just (deleteFindMin x)
 
 -- | /O(log n)/. Retrieves the maximal element of the multiset, and the set stripped from that element
 -- @fail@s (in the monad) when passed an empty multiset.
-maxView :: Monad m => IntMultiSet -> m (Key, IntMultiSet)
+maxView :: IntMultiSet -> Maybe (Key, IntMultiSet)
 maxView x
-  | null x    = fail "IntMultiSet.maxView: empty multiset"
-  | otherwise = return (deleteFindMin x)
+  | null x    = Nothing
+  | otherwise = Just (deleteFindMin x)
 
 {--------------------------------------------------------------------
   Union, Difference, Intersection
diff --git a/Data/MultiSet.hs b/Data/MultiSet.hs
--- a/Data/MultiSet.hs
+++ b/Data/MultiSet.hs
@@ -136,7 +136,11 @@
             , valid
             ) where
 
-import Prelude hiding (filter,foldr,null,map,concatMap)
+import Prelude hiding (filter,foldr,null,map,concatMap
+#if __GLASGOW_HASKELL__ >= 709
+  ,join
+#endif
+  )
 import Data.Monoid (Monoid(..))
 import Data.Typeable ()
 import qualified Data.Foldable as Foldable (Foldable(foldr))
@@ -342,19 +346,19 @@
 
 -- | /O(log n)/. Retrieves the minimal element of the multiset,
 --   and the set with that element removed.
---   @fail@s (in the monad) when passed an empty multiset.
-minView :: Monad m => MultiSet a -> m (a, MultiSet a)
+--   Returns @Nothing@ when passed an empty multiset.
+minView :: MultiSet a -> Maybe (a, MultiSet a)
 minView x
-  | null x    = fail "MultiSet.minView: empty multiset"
-  | otherwise = return (deleteFindMin x)
+  | null x    = Nothing
+  | otherwise = Just (deleteFindMin x)
 
 -- | /O(log n)/. Retrieves the maximal element of the multiset,
 --   and the set with that element removed.
---   @fail@s (in the monad) when passed an empty multiset.
-maxView :: Monad m => MultiSet a -> m (a, MultiSet a)
+--   Returns @Nothing@ when passed an empty multiset.
+maxView :: MultiSet a -> Maybe (a, MultiSet a)
 maxView x
-  | null x    = fail "MultiSet.maxView: empty multiset"
-  | otherwise = return (deleteFindMin x)
+  | null x    = Nothing
+  | otherwise = Just (deleteFindMin x)
 
 {--------------------------------------------------------------------
   Union, Difference, Intersection
@@ -419,7 +423,7 @@
 
 -- | /O(n*log n)/. 
 -- @'map' f s@ is the multiset obtained by applying @f@ to each element of @s@.
-map :: (Ord a, Ord b) => (a->b) -> MultiSet a -> MultiSet b
+map :: (Ord b) => (a->b) -> MultiSet a -> MultiSet b
 map f = MS . Map.mapKeysWith (+) f . unMS
 
 -- | /O(n)/. The 
@@ -435,7 +439,7 @@
 mapMonotonic f = MS . Map.mapKeysMonotonic f . unMS
 
 -- | /O(n)/. Map and collect the 'Just' results.
-mapMaybe :: (Ord a, Ord b) => (a -> Maybe b) -> MultiSet a -> MultiSet b
+mapMaybe :: (Ord b) => (a -> Maybe b) -> MultiSet a -> MultiSet b
 mapMaybe f = fromOccurList . mapMaybe' . toOccurList
   where mapMaybe' [] = []
         mapMaybe' ((x,n):xs) = case f x of
@@ -443,7 +447,7 @@
            Nothing ->          mapMaybe' xs
 
 -- | /O(n)/. Map and separate the 'Left' and 'Right' results.
-mapEither :: (Ord a, Ord b, Ord c) => (a -> Either b c) -> MultiSet a -> (MultiSet b, MultiSet c)
+mapEither :: (Ord b, Ord c) => (a -> Either b c) -> MultiSet a -> (MultiSet b, MultiSet c)
 mapEither f = (\(ls,rs) -> (fromOccurList ls, fromOccurList rs)) . mapEither' . toOccurList
   where mapEither' [] = ([],[])
         mapEither' ((x,n):xs) = case f x of
@@ -452,12 +456,12 @@
 
 
 -- | /O(n)/. Apply a function to each element, and take the union of the results
-concatMap :: (Ord a, Ord b) => (a -> [b]) -> MultiSet a -> MultiSet b
+concatMap :: (Ord b) => (a -> [b]) -> MultiSet a -> MultiSet b
 concatMap f = fromOccurList . Map.foldrWithKey mapF [] . unMS
   where mapF x occ rest = List.map (\y -> (y,occ)) (f x) ++ rest
 
 -- | /O(n)/. Apply a function to each element, and take the union of the results
-unionsMap :: (Ord a, Ord b) => (a -> MultiSet b) -> MultiSet a -> MultiSet b
+unionsMap :: (Ord b) => (a -> MultiSet b) -> MultiSet a -> MultiSet b
 unionsMap f = unions . List.map timesF . toOccurList
   where timesF (ms,1) = f ms
         timesF (ms,n) = MS . Map.map (*n) . unMS $ f ms
@@ -469,7 +473,7 @@
         times (ms,n) = MS . Map.map (*n) . unMS $ ms
 
 -- | /O(n)/. The monad bind operation, (>>=), for multisets.
-bind :: (Ord a, Ord b) => MultiSet a -> (a -> MultiSet b) -> MultiSet b
+bind :: (Ord b) => MultiSet a -> (a -> MultiSet b) -> MultiSet b
 bind = flip unionsMap
 
 {--------------------------------------------------------------------
diff --git a/include/Typeable.h b/include/Typeable.h
--- a/include/Typeable.h
+++ b/include/Typeable.h
@@ -14,46 +14,25 @@
 #ifndef TYPEABLE_H
 #define TYPEABLE_H
 
-#ifdef __GLASGOW_HASKELL__
-
---  // For GHC, we can use DeriveDataTypeable + StandaloneDeriving to
---  // generate the instances.
-
+#if __GLASGOW_HASKELL__ >= 707
 #define INSTANCE_TYPEABLE0(tycon,tcname,str) deriving instance Typeable tycon
+#define INSTANCE_TYPEABLE1(tycon,tcname,str) deriving instance Typeable tycon
+#define INSTANCE_TYPEABLE2(tycon,tcname,str) deriving instance Typeable tycon
+#elif defined(__GLASGOW_HASKELL__)
+#define INSTANCE_TYPEABLE0(tycon,tcname,str) deriving instance Typeable tycon
 #define INSTANCE_TYPEABLE1(tycon,tcname,str) deriving instance Typeable1 tycon
 #define INSTANCE_TYPEABLE2(tycon,tcname,str) deriving instance Typeable2 tycon
 #define INSTANCE_TYPEABLE3(tycon,tcname,str) deriving instance Typeable3 tycon
-
-#else /* !__GLASGOW_HASKELL__ */
-
-#define INSTANCE_TYPEABLE0(tycon,tcname,str) \
-tcname :: TyCon; \
-tcname = mkTyCon str; \
-instance Typeable tycon where { typeOf _ = mkTyConApp tcname [] }
-
-#define INSTANCE_TYPEABLE1(tycon,tcname,str) \
-tcname = mkTyCon str; \
-instance Typeable1 tycon where { typeOf1 _ = mkTyConApp tcname [] }; \
-instance Typeable a => Typeable (tycon a) where { typeOf = typeOfDefault }
-
-#define INSTANCE_TYPEABLE2(tycon,tcname,str) \
-tcname = mkTyCon str; \
-instance Typeable2 tycon where { typeOf2 _ = mkTyConApp tcname [] }; \
-instance Typeable a => Typeable1 (tycon a) where { \
-  typeOf1 = typeOf1Default }; \
-instance (Typeable a, Typeable b) => Typeable (tycon a b) where { \
-  typeOf = typeOfDefault }
-
-#define INSTANCE_TYPEABLE3(tycon,tcname,str) \
-tcname = mkTyCon str; \
-instance Typeable3 tycon where { typeOf3 _ = mkTyConApp tcname [] }; \
-instance Typeable a => Typeable2 (tycon a) where { \
-  typeOf2 = typeOf2Default }; \
-instance (Typeable a, Typeable b) => Typeable1 (tycon a b) where { \
-  typeOf1 = typeOf1Default }; \
-instance (Typeable a, Typeable b, Typeable c) => Typeable (tycon a b c) where { \
-  typeOf = typeOfDefault }
-
-#endif /* !__GLASGOW_HASKELL__ */
+#else
+#define INSTANCE_TYPEABLE0(tycon,tcname,str) tcname :: TyCon; tcname = mkTyCon str; \
+  instance Typeable tycon where { typeOf _ = mkTyConApp tcname [] }
+#define INSTANCE_TYPEABLE1(tycon,tcname,str) tcname :: TyCon; tcname = mkTyCon str; \
+  instance Typeable1 tycon where { typeOf1 _ = mkTyConApp tcname [] }; \
+  instance Typeable a => Typeable (tycon a) where { typeOf = typeOfDefault }
+#define INSTANCE_TYPEABLE2(tycon,tcname,str) tcname :: TyCon; tcname = mkTyCon str; \
+  instance Typeable2 tycon where { typeOf2 _ = mkTyConApp tcname [] }; \
+  instance Typeable a => Typeable1 (tycon a) where { typeOf1 = typeOf1Default }; \
+  instance (Typeable a, Typeable b) => Typeable (tycon a b) where { typeOf = typeOfDefault }
+#endif
 
 #endif
diff --git a/multiset.cabal b/multiset.cabal
--- a/multiset.cabal
+++ b/multiset.cabal
@@ -1,5 +1,5 @@
 name:             multiset
-version:          0.2.2
+version:          0.3.0
 author:           Twan van Laarhoven
 maintainer:       twanvl@gmail.com
 bug-reports:      https://github.com/twanvl/multiset/issues
