diff --git a/Boolean.cabal b/Boolean.cabal
--- a/Boolean.cabal
+++ b/Boolean.cabal
@@ -1,6 +1,6 @@
 Name:                Boolean
-Version:             0.1.2
-Synopsis:            Generalized booleans
+Version:             0.2
+Synopsis:            Generalized booleans and numbers
 Category:            Data
 Cabal-Version:       >= 1.6
 Description:
@@ -8,12 +8,13 @@
   Starting with 0.1.0, this package uses type families.
   Up to version 0.0.2, it used MPTCs with functional dependencies.
   My thanks to Andy Gill for suggesting & helping with the change.
-  Thanks also to Alex Horsman for the overloading module.
+  Thanks also to Alex Horsman for Data.Boolean.Overload and to
+  Jan Bracker for Data.Boolean.Numbers.
   .
-  Copyright 2009-2012 Conal Elliott; BSD3 license.
+  Copyright 2009-2013 Conal Elliott; BSD3 license.
 Author:              Conal Elliott
 Maintainer:          conal@conal.net
-Copyright:           (c) 2009-2012 by Conal Elliott
+Copyright:           (c) 2009-2013 by Conal Elliott
 License:             BSD3
 License-File:        COPYING
 Stability:           experimental
@@ -30,6 +31,7 @@
   Exposed-Modules:
                        Data.Boolean
                        Data.Boolean.Overload
+                       Data.Boolean.Numbers
   ghc-options:         -Wall
 
 --  ghc-prof-options:    -prof -auto-all 
diff --git a/src/Data/Boolean.hs b/src/Data/Boolean.hs
--- a/src/Data/Boolean.hs
+++ b/src/Data/Boolean.hs
@@ -34,15 +34,16 @@
 ----------------------------------------------------------------------
 
 module Data.Boolean
-  (
-    Boolean(..), BooleanOf, IfB(..), boolean, cond, crop
-  , EqB(..), OrdB(..), RealFloatB(..), minB, maxB, sort2B
+  ( Boolean(..), BooleanOf, IfB(..)
+  , boolean, cond, crop
+  , EqB(..), OrdB(..)
+  , minB, maxB, sort2B
+  , guardedB, caseB
   ) where
 
 import Data.Monoid (Monoid,mempty)
 import Control.Applicative (Applicative(pure),liftA2,liftA3)
 
-
 {--------------------------------------------------------------------
     Classes
 --------------------------------------------------------------------}
@@ -82,6 +83,16 @@
 crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a
 crop r f = cond r f mempty
 
+-- | A generalized replacement for guards and chained ifs.
+guardedB :: (IfB b, bool ~ BooleanOf b) => bool -> [(bool,b)] -> b -> b
+guardedB _ []        e = e
+guardedB a ((c,b):l) e = ifB c b (guardedB a l e)
+
+-- | A generalized version of a case like control structure.
+caseB :: (IfB b, bool ~ BooleanOf b) => a -> [(a -> bool, b)] -> b -> b
+caseB _ []        e = e
+caseB x ((p,b):l) e = ifB (p x) b (caseB x l e)
+
 infix  4  ==*, /=*
 
 -- | Types with equality.  Minimum definition: '(==*)'.
@@ -110,13 +121,8 @@
 sort2B :: (IfB a, OrdB a) => (a,a) -> (a,a)
 sort2B (u,v) = ifB (u <=* v) (u,v) (v,u)
 
-class (Boolean (BooleanOf a), RealFrac a, Floating a) => RealFloatB a where
-  isNaN :: a -> BooleanOf a
-  isInfinite :: a -> BooleanOf a
-  isNegativeZero :: a -> BooleanOf a
-  isIEEE :: a -> BooleanOf a
-  atan2 :: a -> a -> a
 
+
 {--------------------------------------------------------------------
     Instances for Prelude types
 --------------------------------------------------------------------}
@@ -152,20 +158,6 @@
 SimpleTy(Char)
 
 -- Similarly for other simple types.
-
-instance RealFloatB Float where
-  isNaN = Prelude.isNaN
-  isInfinite = Prelude.isInfinite
-  isNegativeZero = Prelude.isNegativeZero
-  isIEEE = Prelude.isIEEE
-  atan2 = Prelude.atan2
-
-instance RealFloatB Double where
-  isNaN = Prelude.isNaN
-  isInfinite = Prelude.isInfinite
-  isNegativeZero = Prelude.isNegativeZero
-  isIEEE = Prelude.isIEEE
-  atan2 = Prelude.atan2
 
 -- TODO: Export these macros for external use. I guess I'd want a .h file as in
 -- the applicative-numbers package.
diff --git a/src/Data/Boolean/Numbers.hs b/src/Data/Boolean/Numbers.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Boolean/Numbers.hs
@@ -0,0 +1,210 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleContexts #-}
+
+{-# OPTIONS_GHC -Wall #-}
+
+-- -----------------------------------------------------------------------
+-- |
+-- Module      :  Data.Boolean.Numbers
+-- Copyright   :  (c) Jan Bracker 2013
+-- License     :  BSD3
+-- 
+-- Maintainer  :  jbra@informatik.uni-kiel.de
+-- Stability   :  experimental
+-- 
+-- A generalized version of the class hirarchy for numbers. All
+-- functions that would break a potential deep embedding are removed
+-- or generalized to support deep embeddings.
+-- 
+-- The class hirarchy for numeric types keeps as close as possible to the 
+-- 'Prelude' hirarchy. A great part of the default implementation and comments
+-- are copied and adopted from 'Prelude'.
+-- -----------------------------------------------------------------------
+
+module Data.Boolean.Numbers 
+  ( NumB(..)
+  , IntegralB(..)
+  , RealFracB(..)
+  , RealFloatB(..)
+  , evenB, oddB
+  , fromIntegralB
+  ) where
+
+import Prelude hiding 
+  ( quotRem, divMod
+  , quot, rem
+  , div, mod
+  , properFraction
+  , fromInteger, toInteger )
+import qualified Prelude as P
+
+import Control.Arrow (first)
+
+import Data.Boolean
+
+{--------------------------------------------------------------------
+    Misc
+--------------------------------------------------------------------}
+
+infixr 9 .:
+
+-- Double composition. (Aka "result.result". See semantic editor combinators.)
+(.:) :: (c -> c') -> (a -> b -> c) -> (a -> b -> c')
+(.:) = (.).(.)
+
+(##) :: (a -> b -> c) -> (a -> b -> d) -> a -> b -> (c,d)
+(f ## g) x y = (f x y, g x y)
+
+-- -----------------------------------------------------------------------
+-- Generalized Number Class Hirarchy
+-- -----------------------------------------------------------------------
+
+-- | An extension of 'Num' that supplies the integer type of a 
+--   given number type and a way to create that number from the 
+--   integer.
+class Num a => NumB a where
+  -- | The accociated integer type of the number.
+  type IntegerOf a
+  -- | Construct the number from the associated integer.
+  fromIntegerB :: IntegerOf a -> a
+
+-- | A deep embedded version of 'Integral'.
+--   Integral numbers, supporting integer division.
+--   
+--   Minimal complete definition is either 'quotRem' and 'divMod'
+--   or the other four functions. Besides that 'toIntegerB' always
+--   has to be implemented.
+class (NumB a, OrdB a) => IntegralB a where
+  -- | Integer division truncated towards zero.
+  quot :: a -> a -> a
+  quot = fst .: quotRem
+  -- | Integer reminder, satisfying:
+  --   @(x `quot` y) * y + (x `rem` y) == x@
+  rem :: a -> a -> a
+  rem = snd .: quotRem
+  -- | Integer division truncated toward negative infinity.
+  div :: a -> a -> a
+  div = fst .: divMod
+  -- | Integer modulus, satisfying:
+  --   @(x `div` y) * y + (x `mod` y) == x@
+  mod :: a -> a -> a
+  mod = snd .: divMod
+  -- | Simultaneous 'quot' and 'rem'.
+  quotRem :: a -> a -> (a,a)
+  quotRem = quot ## rem
+  -- | Simultaneous 'div' and 'mod'.
+  divMod :: a -> a -> (a,a)
+  divMod  = div ## mod
+  -- | Create a integer from this integral.
+  toIntegerB :: a -> IntegerOf a
+
+-- | Deep embedded version of 'RealFloat'.
+--   Extracting components of fractions.
+--   
+--   Minimal complete definition: 'properFraction', 
+--   'round', 'floor' and 'ceiling'.
+class (NumB a, OrdB a, Fractional a) => RealFracB a where
+  -- | The function 'properFraction' takes a real fractional number @x@
+  -- and returns a pair @(n,f)@ such that @x = n+f@, and:
+  -- 
+  -- * @n@ is an integral number with the same sign as @x@; and
+  -- 
+  -- * @f@ is a fraction with the same type and sign as @x@,
+  --   and with absolute value less than @1@.
+  --   
+  -- The default definitions of the 'ceiling', 'floor', 'truncate'
+  -- and 'round' functions are in terms of 'properFraction'.
+  properFraction :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> (b, a)
+  -- | @'truncate' x@ returns the integer nearest @x@ between zero and @x@
+  truncate :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+  truncate = fst . properFraction
+  -- | @'round' x@ returns the nearest integer to @x@;
+  --   the even integer if @x@ is equidistant between two integers
+  round :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+  -- | @'ceiling' x@ returns the least integer not less than @x@
+  ceiling :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+  -- | @'floor' x@ returns the greatest integer not greater than @x@.
+  floor :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+
+-- | Deep embedded version of 'RealFloat'.
+--   Efficient, machine-independent access to the components of a
+--   floating-point number.
+--   
+--   A complete definition has to define all functions.
+class (Boolean (BooleanOf a), RealFracB a, Floating a) => RealFloatB a where
+  -- | 'true' if the argument is an IEEE \"not-a-number\" (NaN) value.
+  isNaN :: a -> BooleanOf a
+  -- | 'true' if the argument is an IEEE infinity or negative infinity.
+  isInfinite :: a -> BooleanOf a
+  -- | 'true' if the argument is an IEEE negative zero.
+  isNegativeZero :: a -> BooleanOf a
+  -- | 'true' if the argument is an IEEE floating point number.
+  isIEEE :: a -> BooleanOf a
+  -- | a version of arctangent taking two real floating-point arguments.
+  --   For real floating @x@ and @y@, @'atan2' y x@ computes the angle
+  --   (from the positive x-axis) of the vector from the origin to the
+  --   point @(x,y)@.  @'atan2' y x@ returns a value in the range [@-pi@,
+  --   @pi@].  It follows the Common Lisp semantics for the origin when
+  --   signed zeroes are supported.  @'atan2' y 1@, with @y@ in a type
+  --   that is 'RealFloatB', should return the same value as @'atan' y@.
+  atan2 :: a -> a -> a
+
+-- -----------------------------------------------------------------------
+-- Generalized Number Utility Functions
+-- -----------------------------------------------------------------------
+
+-- | Variant of 'even' for generalized booleans.
+evenB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a
+evenB n = n `rem` 2 ==* 0
+
+-- | Variant of 'odd' for generalized booleans.
+oddB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a
+oddB = notB . evenB
+
+-- | Variant of 'fromIntegral' for generalized booleans.
+fromIntegralB :: (IntegerOf a ~ IntegerOf b, IntegralB a, NumB b) => a -> b
+fromIntegralB = fromIntegerB . toIntegerB
+
+-- -----------------------------------------------------------------------
+-- Default Class Instances for Basic Types
+-- -----------------------------------------------------------------------
+
+-- | Only for internal use.
+fromInteger' :: (Integer ~ IntegerOf b, NumB b) => Integer -> b
+fromInteger' = fromIntegralB
+
+#define DefaultNumBInstance(Ty) \
+instance NumB (Ty) where {\
+  type IntegerOf (Ty) = Integer ;\
+  fromIntegerB = P.fromInteger }
+
+#define DefaultIntegralBInstance(Ty) \
+instance IntegralB (Ty) where {\
+  quotRem = P.quotRem ;\
+  divMod = P.divMod ;\
+  toIntegerB = P.toInteger }
+
+#define DefaultRealFracFloatBInstance(Ty) \
+instance RealFracB (Ty) where {\
+  properFraction = first fromInteger' . P.properFraction ;\
+  round          = fromInteger' . P.round ;\
+  floor          = fromInteger' . P.floor ;\
+  ceiling        = fromInteger' . P.ceiling };\
+instance RealFloatB (Ty) where {\
+  isNaN          = P.isNaN ;\
+  isInfinite     = P.isInfinite ;\
+  isNegativeZero = P.isNegativeZero ;\
+  isIEEE         = P.isIEEE ;\
+  atan2          = P.atan2 }
+
+DefaultNumBInstance(Int)
+DefaultNumBInstance(Integer)
+DefaultNumBInstance(Float)
+DefaultNumBInstance(Double)
+
+DefaultIntegralBInstance(Int)
+DefaultIntegralBInstance(Integer)
+
+DefaultRealFracFloatBInstance(Float)
+DefaultRealFracFloatBInstance(Double)
