diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,7 +1,6 @@
 # Changelog for rg
 
-## Unreleased changes
-
   * 1.0.0.0: first release
   * 1.1.0.0: add RgText, BE derivation
-  - 1.2.0.0: first public release
+  * 1.2.0.0: first public release
+  * 1.3.0.0: add rgCoreMethods
diff --git a/rg.cabal b/rg.cabal
--- a/rg.cabal
+++ b/rg.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 527175fcfe23d40d0a87e869a4613c10ea692ae5c67e26c181bae7d7f71687ee
+-- hash: 3cabf1da9ca011c22c7a2edbd99264013666a9ece5fb53cf4229c97323160ee0
 
 name:           rg
-version:        1.2.0.0
+version:        1.3.0.0
 synopsis:       A dynamic/unbounded alternative to Bounded Enum
 description:    Please see the README on GitHub at <https://github.com/cdornan/rg#readme>
 category:       Types
diff --git a/src/Data/Rg.hs b/src/Data/Rg.hs
--- a/src/Data/Rg.hs
+++ b/src/Data/Rg.hs
@@ -1,9 +1,12 @@
 {-# LANGUAGE RecordWildCards            #-}
 {-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
 
 module Data.Rg
   ( Rg(..)
+  , RgCoreMethods
+  , rgCoreMethodsBE
   , RgText(..)
   , BE(..)
   , Range
@@ -13,6 +16,7 @@
   ) where
 
 import           Data.Array
+import           Data.Coerce
 import qualified Data.HashMap.Strict  as HM
 import           Data.Maybe
 import           Data.Possibly
@@ -25,46 +29,60 @@
 -- can be dynamically determined from each value in the type (see 'sizeRg')
 class Rg rg where
   -- | the number of values in the enumeration; sizeRg sz > 0
-  sizeRg      :: rg -> Int
+  sizeRg        :: rg -> Int
+  sizeRg = _rcm_sizeRg rgCoreMethods
 
   -- | the nth item in the enumeration (first is 0)
-  toRg        :: rg -> Int -> Maybe rg
+  toRg          :: rg -> Int -> Maybe rg
+  toRg   = _rcm_toRg   rgCoreMethods
 
   -- | place in the enumation (first is 0)
-  fromRg      :: rg -> Int
+  fromRg        :: rg -> Int
+  fromRg = _rcm_fromRg rgCoreMethods
 
+  -- | an alternative way of specifying sizeRg, toRg and fromRg
+  rgCoreMethods :: RgCoreMethods rg
+  rgCoreMethods =
+    RgCoreMethods
+      { _rcm_sizeRg = sizeRg
+      , _rcm_toRg   = toRg
+      , _rcm_fromRg = fromRg
+      }
+
+  {-# MINIMAL sizeRg, toRg, fromRg | rgCoreMethods #-}
+
   -- | first item in the enumeration
-  minRg       :: rg -> rg
-  minRg    = fromMaybe oops . flip toRg 0
+  minRg         :: rg -> rg
+  minRg     = fromMaybe oops . flip toRg 0
     where
-      oops = error "minRg: no minimum value in range"
+      oops  = error "minRg: no minimum value in range"
 
   -- | last item in the enumeration
-  maxRg       :: rg -> rg
-  maxRg rg = fromMaybe oops $ toRg rg n
+  maxRg         :: rg -> rg
+  maxRg rg  = fromMaybe oops $ toRg rg n
     where
-      n    = sizeRg rg - 1
-      oops = error "maxRg: no maximum value in range"
+      n     = sizeRg rg - 1
+      oops  = error "maxRg: no maximum value in range"
 
   -- | next item in the enumeration (Nothing if already last)
-  succRg      :: rg -> Maybe rg
+  succRg        :: rg -> Maybe rg
   succRg rg = toRg rg $ fromRg rg + 1
 
   -- | previous item in the enumeration (Nothing if already first)
-  predRg      :: rg -> Maybe rg
+  predRg        :: rg -> Maybe rg
   predRg rg = toRg rg $ fromRg rg - 1
 
   -- | list given items in the enumeration
-  allListRg   :: rg -> [rg]
+  allListRg     :: rg -> [rg]
   allListRg rg = listRg rg [0..]
 
   -- | list given items in the enumeration, stopping as soon as an index is
   -- out of range
-  listRg      :: rg -> [Int] -> [rg]
+  listRg        :: rg -> [Int] -> [rg]
   listRg rg is = catMaybes $ takeWhile isJust [ toRg rg i | i<-is ]
 
   -- | list given items in the enumeration as a 'V.Vector'
-  allVectorRg :: rg -> [rg]
+  allVectorRg   :: rg -> [rg]
   allVectorRg rg = listRg rg [0..]
 
   -- | list the items in the enumeration as a 'V.Vector', stopping as soon as an
@@ -73,7 +91,31 @@
   vectorRg rg is = V.fromList $ listRg rg is
 
 
+
 -------------------------------------------------------------------------------
+-- RgCoreMethods
+-------------------------------------------------------------------------------
+
+-- | dynamically encapsulates the core 'Rg' methods
+data RgCoreMethods rg =
+  RgCoreMethods
+    { _rcm_sizeRg :: rg -> Int
+    , _rcm_toRg   :: rg -> Int -> Maybe rg
+    , _rcm_fromRg :: rg -> Int
+    }
+
+-- | if you want to create an 'Rg' from a 'Bounded' 'Enum' you can bind
+-- 'rgCoreMethods' to this function
+rgCoreMethodsBE :: forall rg . (Bounded rg, Enum rg) => RgCoreMethods rg
+rgCoreMethodsBE =
+    RgCoreMethods
+      { _rcm_sizeRg = coerce (sizeRg :: BE rg -> Int)
+      , _rcm_toRg   = coerce (toRg   :: BE rg -> Int -> Maybe (BE rg))
+      , _rcm_fromRg = coerce (fromRg :: BE rg -> Int)
+      }
+
+
+-------------------------------------------------------------------------------
 -- class RgText
 -------------------------------------------------------------------------------
 
@@ -154,7 +196,6 @@
 -- hashmap_t
 -------------------------------------------------------------------------------
 
--- | 'T.Text' 'HM.HashMap' based on 'renderEnumText' representation
 hashmap_t :: RgText e => e -> HM.HashMap T.Text e
 hashmap_t x = HM.fromList
     [ (fmt $ build c,c)
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -38,6 +38,16 @@
       , testCase "fromRg False"   $ 0                  @=? fromRg    (BE False)
       , testCase "fromRg True"    $ 1                  @=? fromRg    (BE True )
       ]
+    , testGroup "rgCoreMethodsBE"
+      [ testCase "sizeRg True"    $ 2                  @=? sizeRg    True
+      , testCase "sizeRg False"   $ 2                  @=? sizeRg    False
+      , testCase "toRg 0"         $ Just False         @=? toRg      False 0
+      , testCase "toRg 1"         $ Just True          @=? toRg      False 1
+      , testCase "toRg 3"         $ Nothing            @=? toRg      False 2
+      , testCase "allListRg"      $ [False,True]       @=? allListRg False
+      , testCase "fromRg False"   $ 0                  @=? fromRg    False
+      , testCase "fromRg True"    $ 1                  @=? fromRg    True
+      ]
     , testGroup "RgText"
       [ testCase "TRUE"    $ Right (BE True ) @=? parseRgText (BE False) "TRUE"
       , testCase "FALSE"   $ Right (BE False) @=? parseRgText (BE True ) "FALSE"
@@ -52,6 +62,8 @@
     msg = "parseRgText: enumeration not recognised: \"false\""
 
 instance RgText (BE Bool)
+
+instance Rg Bool where rgCoreMethods = rgCoreMethodsBE
 
 instance Buildable (BE Bool) where
   build (BE True)  = "TRUE"
