diff --git a/aern2-real.cabal b/aern2-real.cabal
--- a/aern2-real.cabal
+++ b/aern2-real.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: c67f4a27fe078f22681a08242d1e8a0ed286ea4b52c96a755e45c8ce04d402c7
+-- hash: 5876d1cb06216bd03fa7525216359040a103cbaa847257f879df367b53fb413c
 
 name:           aern2-real
-version:        0.2.6.0
+version:        0.2.7.0
 synopsis:       Real numbers as sequences of MPBalls
 description:    Please see the README on GitHub at <https://github.com/michalkonecny/aern2/#readme>
 category:       Math
@@ -61,12 +61,12 @@
   ghc-options: -Wall
   build-depends:
       QuickCheck
-    , aern2-mp >=0.2.6
+    , aern2-mp >=0.2.7
     , base ==4.*
     , collect-errors >=0.1.5
     , hspec
     , integer-logarithms
-    , mixed-types-num >=0.5.7
+    , mixed-types-num >=0.5.8
   default-language: Haskell2010
 
 test-suite aern2-real-test
@@ -93,11 +93,11 @@
   ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
   build-depends:
       QuickCheck
-    , aern2-mp >=0.2.6
+    , aern2-mp >=0.2.7
     , aern2-real
     , base ==4.*
     , collect-errors >=0.1.5
     , hspec
     , integer-logarithms
-    , mixed-types-num >=0.5.7
+    , mixed-types-num >=0.5.8
   default-language: Haskell2010
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,9 @@
 # Change log for aern2-real
 
+* v 0.2.7 2021-06-02
+  * add RealNumber type class
+* v 0.2.6 2021-05-29
+  * adapt to new ppow operations
 * v 0.2.5 2021-05-27
   * CanSelect moved to aern2-mp
 * v 0.2.4 2021-05-26
diff --git a/examples/AERN2/Real/Examples/ClosestPairDist.hs b/examples/AERN2/Real/Examples/ClosestPairDist.hs
--- a/examples/AERN2/Real/Examples/ClosestPairDist.hs
+++ b/examples/AERN2/Real/Examples/ClosestPairDist.hs
@@ -2,8 +2,8 @@
 {-# OPTIONS_GHC -Wno-missing-signatures #-}
 {-# OPTIONS_GHC -Wno-partial-type-signatures #-}
 {-|
-    Module      :  AERN2.Real.Introduction
-    Description :  aern2-real introductory examples
+    Module      :  AERN2.Real.Examples..ClosestPairDist
+    Description :  Example: Computing shortest distance among a set of 1D points
     Copyright   :  (c) Michal Konecny
     License     :  BSD3
 
@@ -11,7 +11,9 @@
     Stability   :  experimental
     Portability :  portable
 
-    You can run the examples in this file in ghci.
+    Example: Computing shortest distance among a set of 1D points.
+
+    You can run this file in ghci.
     If you installed AERN2 using the official instructions,
     you can start ghci using the following command in the base
     folder:
@@ -29,57 +31,131 @@
 import Test.QuickCheck
 import qualified Data.List as List
 
-import AERN2.MP
 import AERN2.Real
 
--- import Debug.Trace
-
--- define a short name for the type of real numbers:
-type R = CReal
-
 ----------------------------------
 -- Finding the smallest distance within a set of real numbers
 ----------------------------------
 
-closestPairDist_naive ::
-  _ => [t] -> t
+distance :: 
+  (CanAbsSameType t, CanSubSameType t)
+  =>
+  (t, t) -> t
+distance (a,b) = abs (a-b)
+
+closestPairDist_naive :: 
+  (CanMinMaxSameType t, CanAbsSameType t, CanSubSameType t) 
+  =>
+  [t] -> t
 closestPairDist_naive pts
   | length pts < 2 = error "closestPairDist_naive: too few points"
   | otherwise =
       (foldl1 min (map distance (distinctPairs pts)))
+  where
+  distinctPairs :: [t] -> [(t,t)]
+  distinctPairs xs = [(x,y) | (x:rest) <- tails1 xs, y <- rest]
 
-distance :: (CanSubSameType t, CanAbsSameType t) => (t, t) -> t
-distance (a,b) = abs (a-b)
+  {-| non-empty tails -}
+  tails1 :: [t] -> [[t]]
+  tails1 list =
+    take (length list - 1) $ List.tails list
 
+{- a version that splits, recurses and merges the results -}
+closestPairDist_split ::
+  (RealNumber r, CanMinMaxSameType r, CanAbsSameType r) 
+  => 
+  [r] -> r
+closestPairDist_split pts
+  | length ptsL < 2 || length ptsR < 2 =
+      closestPairDist_naive pts
+  | otherwise =
+      recurseAndMerge
+  where
+  (ptsL,ptsR) = List.partition isCertainlyLeft pts
+    where
+    isCertainlyLeft x = 
+      isCertainlyTrue $ select (x < a) (x > a - 0.5^100)
+    a = average pts
+  recurseAndMerge =
+    foldl1 min [dL, dLR, dR]
+    where
+    dL = closestPairDist_split ptsL
+    dLR = distance (largest ptsL, smallest ptsR)
+    dR = closestPairDist_split ptsR
+  
+average :: (HasIntegers t, CanAddSameType t, CanDivBy t Integer) => [t] -> t
+average xs = (sum xs) / (length xs)
+
+largest :: (CanMinMaxSameType t) => [t] -> t
+largest pts = foldl1 max pts
+
+smallest :: (CanMinMaxSameType t) => [t] -> t
+smallest pts = foldl1 min pts
+
+{-
+  Helper functions for running tests by hand.
+  -}
+
 closestPairDist_run ::
-  _ =>
-  ([t] -> t) ->
-  Integer -> t
+  (RealNumber r, CanSinCosSameType r, CanMinMaxSameType r, CanAbsSameType r)
+  =>
+  ([r] -> r) -> 
+  Integer -> r
 closestPairDist_run (closestPairDist :: [t] -> t) n =
   closestPairDist [sin (convertExactly i :: t) | i <- [1..n]]
 
-closestPairDist_run_naive :: Integer -> R
+closestPairDist_run_naive :: 
+  (RealNumber r, CanSinCosSameType r, CanMinMaxSameType r, CanAbsSameType r) 
+  => 
+  Integer -> r
 closestPairDist_run_naive =
   closestPairDist_run closestPairDist_naive 
 
-closestPairDist_run_split :: Integer -> R
+closestPairDist_run_split ::
+  (RealNumber r, CanSinCosSameType r, CanMinMaxSameType r, CanAbsSameType r) 
+  => 
+  Integer -> r
 closestPairDist_run_split =
-  closestPairDist_run $ closestPairDist_split compRApprox
+  closestPairDist_run $ closestPairDist_split
 
+closestPairDist_run_naive_CReal :: Integer -> CReal
+closestPairDist_run_naive_CReal = closestPairDist_run_naive
+
+closestPairDist_run_naive_WCP :: Integer -> CReal
+closestPairDist_run_naive_WCP n = crealFromWithCurrentPrec $ closestPairDist_run_naive n
+
+closestPairDist_run_split_CReal :: Integer -> CReal
+closestPairDist_run_split_CReal = closestPairDist_run_split
+
+closestPairDist_run_split_WCP :: Integer -> CReal
+closestPairDist_run_split_WCP n = crealFromWithCurrentPrec $ closestPairDist_run_split n
+
+
 {- Example runs:
 
-*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_naive 1000 ? (prec 1000)
+*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_naive_CReal 1000 ? (prec 1000)
 [0.00000013295546744391165086... ± ~0.0000 ~2^(-1221)]
 (13.80 secs, 12,017,593,904 bytes)
 
-*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_split 1000 ? (prec 1000)
+*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_naive_WCP 1000 ? (prec 1000)
 [0.00000013295546744391165086... ± ~0.0000 ~2^(-1221)]
-(4.95 secs, 9,979,768,504 bytes)
+(7.12 secs, 9,187,727,688 bytes)
 
+*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_split_CReal 1000 ? (prec 1000)
+[0.00000013295546744391165086... ± ~0.0000 ~2^(-1221)]
+(2.59 secs, 4,659,949,752 bytes)
+
+*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_split_WCP 1000 ? (prec 1000)
+[0.00000013295546744391165086... ± ~0.0000 ~2^(-1221)]
+(1.11 secs, 2,245,453,016 bytes)
+
 -}
 
 {- specification and randomised tests -}
 
+closestPairDist_spec :: 
+  _ =>
+  ([r] -> r) -> (r -> t) -> [b] -> Property
 closestPairDist_spec closestPairDist (getFinite :: r -> t) numbers =
   (length numbers) < 2
   .||.
@@ -88,59 +164,9 @@
   numbersR = map convertExactly numbers :: [r]
   a ?==?$ b = printArgsIfFails2 "?==?" (?==?) a b
 
+closestPairDist_runTests1 :: IO ()
 closestPairDist_runTests1 =
-  quickCheck (closestPairDist_spec (closestPairDist_split compRApprox) (?bits 100) :: [Integer] -> Property)
-closestPairDist_runTests2 =
-  quickCheck (closestPairDist_spec (closestPairDist_split compMPBall) id :: [Integer] -> Property)
+  quickCheck (closestPairDist_spec (closestPairDist_split :: [CReal] -> CReal) (?bits 100) :: [Integer] -> Property)
 
 sample_integers = sample' (arbitrary :: Gen [Integer]) >>= mapM_ print
 sample_rationals = sample' (arbitrary :: Gen [Rational]) >>= mapM_ print
-
-{- a version that splits, recurses and merges the results -}
-closestPairDist_split ::
-  _ => (t -> t -> Bool) -> [t] -> t
-closestPairDist_split (.<) pts
-  | length ptsL < 2 || length ptsR < 2 =
-      closestPairDist_naive pts
-  | otherwise =
-      recurseAndMerge
-  where
-  (ptsL,ptsR) = List.partition isCertainlyLeft pts
-    where
-    isCertainlyLeft x = x .< average pts
-  recurseAndMerge =
-    foldl1 min [dL, dLR, dR]
-    where
-    dL = closestPairDist_split (.<) ptsL
-    dLR = distance (largest ptsL, smallest ptsR)
-    dR = closestPairDist_split (.<) ptsR
-
-compRApprox :: R -> R -> Bool
-compRApprox a b = (a?ac) !<! (b?ac)
-  where
-  ac = bits 100
-
-compMPBall :: MPBall -> MPBall -> Bool
-compMPBall = (!<!)
-
-{- auxiliary functions -}
-
--- hull :: MPBall -> MPBall -> MPBall
--- hull = hullMPBall
-
-average :: (HasIntegers t, CanAddSameType t, CanDivBy t Integer) => [t] -> t
-average xs = (sum xs) / (length xs)
-
-largest :: (CanMinMaxSameType t) => [t] -> t
-largest pts = foldl1 max pts
-
-smallest :: (CanMinMaxSameType t) => [t] -> t
-smallest pts = foldl1 min pts
-
-distinctPairs :: [t] -> [(t,t)]
-distinctPairs xs = [(x,y) | (x:rest) <- tails1 xs, y <- rest]
-
-{-| non-empty tails -}
-tails1 :: [t] -> [[t]]
-tails1 list =
-  take (length list - 1) $ List.tails list
diff --git a/examples/AERN2/Real/Examples/Introduction.hs b/examples/AERN2/Real/Examples/Introduction.hs
--- a/examples/AERN2/Real/Examples/Introduction.hs
+++ b/examples/AERN2/Real/Examples/Introduction.hs
@@ -31,6 +31,7 @@
 import qualified Numeric.CollectErrors as CN
 
 import AERN2.MP
+import AERN2.MP.WithCurrentPrec
 import AERN2.Real
 
 -- import Debug.Trace
@@ -263,21 +264,28 @@
 
 -}
 
------------------------------------------
--- Cauchy reals vs iRRAM style execution
------------------------------------------
 
-logistic1 :: _ => Rational -> Integer -> t -> t
-logistic1 c n x0 =
+logistic :: (RealNumber t) => Rational -> Integer -> t -> t
+logistic c n x0 =
   (foldl1 (.) (replicate n lg)) x0
   where
   lg x = c * x * (1-x)
 
+logistic1 :: (RealNumber t) => Integer -> t
+logistic1 n = logistic 3.82 n (convertExactly 0.5)
+
 logistic1_CReal_run :: Integer -> CReal
-logistic1_CReal_run n = logistic1 3.82 n (creal 0.5)
+logistic1_CReal_run n = 
+  logistic1 n
 
--- TODO: define logistic1_iter
+logistic1_WithCurrentPrec_run :: Integer -> CReal
+logistic1_WithCurrentPrec_run n = 
+  crealFromWithCurrentPrec $ logistic1 n
 
+logistic1_WithCurrentPrec_p_run :: Integer -> Precision -> CN MPBall
+logistic1_WithCurrentPrec_p_run n p = 
+  runWithPrec p $ logistic1 n
+
 {-  Example uses:
 
 *AERN2.Real.Examples.Introduction> logistic1_CReal_run 100 ? (bits 100)
@@ -286,6 +294,14 @@
 *AERN2.Real.Examples.Introduction> logistic1_CReal_run 10000 ? (bits 100)
 [0.20775682944252359241450861... ± ~0.0000 ~2^(-2566)]
 (2.06 secs, 2,970,188,704 bytes)
+
+*AERN2.Real.Examples.Introduction> logistic1_WithCurrentPrec_run 10000 ? (bits 100)
+[0.20775682944252359241450861... ± ~0.0000 ~2^(-2566)]
+(2.02 secs, 2,897,034,816 bytes)
+
+*AERN2.Real.Examples.Introduction> logistic1_WithCurrentPrec_p_run 10000 (prec 20000)
+[0.20775682944252359241450861... ± ~1.0317e-200 ~2^(-664)]
+(1.05 secs, 1,421,858,848 bytes)
 
 -}
 
diff --git a/src/AERN2/Real.hs b/src/AERN2/Real.hs
--- a/src/AERN2/Real.hs
+++ b/src/AERN2/Real.hs
@@ -16,19 +16,25 @@
    CReal, 
    CSequence (..), 
    creal, HasCReals, CanBeCReal,
-   cseqPrecisions, cseqIndexForPrecision,
+   cseqPrecisions, cseqIndexForPrecision, 
+   cseqFromWithCurrentPrec, cseqFromPrecFunction,
    pi,
+   crealFromWithCurrentPrec, crealFromPrecFunction,
    -- * limits
    HasLimits(..),
    -- * lazy Kleeneans
    CKleenean, CanBeCKleenean, ckleenean, CanSelect(..),
    -- * extracting approximations
-   CanExtractApproximation(..), (?), realWithAccuracy, bits, prec
+   CanExtractApproximation(..), (?), bits, prec,
+   -- * abstract real numbers
+   RealNumber
 )
 where
 
-import AERN2.MP ( bits, prec )
 import AERN2.Limit
+import AERN2.Select
+import AERN2.MP
+import AERN2.MP.WithCurrentPrec
 import AERN2.Real.Type
 import AERN2.Real.Comparisons ()
 import AERN2.Real.CKleenean
@@ -37,58 +43,24 @@
 import AERN2.Real.Elementary (pi)
 -- import AERN2.Real.Tests ()
 
--- imports used in examples below:
-
--- import MixedTypesNumPrelude
--- -- import qualified Prelude as P
+import MixedTypesNumPrelude
+-- import qualified Prelude as P
+import GHC.TypeLits
 
 -- import Text.Printf
 -- -- import AERN2.MP.Dyadic
 
-
--- {- parallel branching -}
-
--- _example_pif :: CauchyReal -> CauchyRealCN
--- _example_pif r =
---   if r < 0 then -r else r -- abs via parallel if
-
--- _example_pif0 :: MPBall -> CN MPBall
--- _example_pif0 r =
---   if r < 0 then -r else r -- abs via parallel if
+class
+    (OrderedField r
+    , HasLimits Int r
+    , HasLimits Integer r
+    , HasLimits Rational r
+    , CanSelect (OrderCompareType r r)
+    , (CanTestCertainly (SelectType (OrderCompareType r r))))
+    => 
+    RealNumber r
 
--- _nsection ::
---   Integer ->
---   (Rational -> CauchyReal) ->
---   (Rational,Rational) ->
---   CauchyRealCN
--- _nsection n f (l,r) =
---   newSeqSimple (cn $ mpBall 0) $ withAccuracy
---   where
---   withAccuracy (me,_) ac@(AccuracySG _ acG) =
---     onSegment (l,r)
---     where
---     onSegment (a,b) =
---       let ab = mpBallP p ((a+b)/!2, (b-a)/!2) in
---       if getAccuracy ab >= ac
---         then cn ab
---         else pick me (map withMidpoint midpoints)
---       where
---       midpoints = [ (i*a + (n-i)*b)/!n | i <- [1..n-1] ]
---       withMidpoint :: Rational -> Sequence (Maybe (CN MPBall))
---       withMidpoint m = newSeqSimple Nothing withAC
---         where
---         withAC (meF, _) acF
---           | fa * fm !<! 0 = Just $ onSegment (a, m)
---           | fm * fb !<! 0 = Just $ onSegment (m, b)
---           | fa * fb !>=! 0 = Just $ err
---           | otherwise = Nothing
---           where
---           fa = ((f a) ?<- meF) acF
---           fm = ((f m) ?<- meF) acF
---           fb = ((f b) ?<- meF) acF
---       err :: CN MPBall
---       err =
---         noValueNumErrorCertainCN $
---           NumError $
---             printf "n-section: function does not have opposite signs on points %s %s" (show a) (show b)
---     p = prec $ fromAccuracy acG + 8
+instance RealNumber CReal
+instance
+    (KnownNat p) => 
+    RealNumber (WithCurrentPrec p (CN MPBall))
diff --git a/src/AERN2/Real/CKleenean.hs b/src/AERN2/Real/CKleenean.hs
--- a/src/AERN2/Real/CKleenean.hs
+++ b/src/AERN2/Real/CKleenean.hs
@@ -14,7 +14,6 @@
 module AERN2.Real.CKleenean
 (
   CKleenean, CanBeCKleenean, ckleenean
-  , CanSelect(..)
 )
 where
 
diff --git a/src/AERN2/Real/Tests.hs b/src/AERN2/Real/Tests.hs
--- a/src/AERN2/Real/Tests.hs
+++ b/src/AERN2/Real/Tests.hs
@@ -41,8 +41,9 @@
 import AERN2.MP.Dyadic
 
 import AERN2.Limit
+import AERN2.Select
 import AERN2.Real.Type
-import AERN2.Real.CKleenean
+-- import AERN2.Real.CKleenean
 import AERN2.Real.Field ()
 import AERN2.Real.Elementary ()
 import AERN2.Real.Limit ()
diff --git a/src/AERN2/Real/Type.hs b/src/AERN2/Real/Type.hs
--- a/src/AERN2/Real/Type.hs
+++ b/src/AERN2/Real/Type.hs
@@ -72,8 +72,8 @@
 cseqFromPrecFunction :: (Precision -> CN b) -> CSequence b
 cseqFromPrecFunction withP = CSequence $ map withP cseqPrecisions
 
-cseqFromWithCurrentPrec :: (forall p. (KnownNat p) => WithCurrentPrec (CN b) p) -> CSequence b
-cseqFromWithCurrentPrec (withCurrentP :: (forall p. (KnownNat p) => WithCurrentPrec (CN b) p)) = 
+cseqFromWithCurrentPrec :: (forall p. (KnownNat p) => WithCurrentPrec p (CN b)) -> CSequence b
+cseqFromWithCurrentPrec (withCurrentP :: (forall p. (KnownNat p) => WithCurrentPrec p (CN b))) = 
   CSequence $ map withP cseqPrecisions
   where
   withP p = runWithPrec p withCurrentP :: CN b
@@ -101,6 +101,9 @@
 crealFromPrecFunction :: (Precision -> CN MPBall) -> CReal
 crealFromPrecFunction = cseqFromPrecFunction
 
+crealFromWithCurrentPrec :: (forall p. (KnownNat p) => WithCurrentPrec p (CN MPBall)) -> CSequence MPBall
+crealFromWithCurrentPrec = cseqFromWithCurrentPrec
+
 {- Extracting approximations -}
 
 class CanExtractApproximation e q where
@@ -131,10 +134,6 @@
         CN.noValueNumErrorPotential $ 
           CN.NumError "failed to find an approximation with sufficient accuracy"
   
-{-| Get a ball approximation of the real number with at least the specified accuracy -}
-realWithAccuracy :: CReal -> Accuracy -> CN MPBall
-realWithAccuracy = extractApproximation
-
 instance CanExtractApproximation (CSequence t) Precision where
   type ExtractedApproximation (CSequence t) Precision = CN t
   extractApproximation (CSequence s) p =
