diff --git a/bidispec.cabal b/bidispec.cabal
--- a/bidispec.cabal
+++ b/bidispec.cabal
@@ -1,5 +1,5 @@
 Name:                bidispec
-Version:             0.1
+Version:             0.1.3
 Synopsis:            Specification of generators and parsers
 Description:
  This is a generalisation of the idea behind the XML pickle/unpickle
@@ -15,6 +15,6 @@
 
 Library
   Hs-Source-Dirs:    src
-  GHC-Options: -Wall
-  Build-Depends:     base >= 3 && < 4, bytestring, mtl
+  GHC-Options:       -Wall -fno-warn-orphans
+  Build-Depends:     base >= 4 && < 5, bytestring, mtl
   Exposed-Modules:   Data.BidiSpec
diff --git a/src/Data/BidiSpec.hs b/src/Data/BidiSpec.hs
--- a/src/Data/BidiSpec.hs
+++ b/src/Data/BidiSpec.hs
@@ -8,23 +8,23 @@
     (Spec, SpecGen, SpecParser(..)
     ,mkSpec, parseBySpec, genBySpec, runSpecParser, rsGen, rsParse
     ,spGet, spGets, spCheck, spFromMaybe, spFromEither
-    ,rsPair, rsTriple, rsQuadruple
+    ,rsPair, rsTriple, rsQuadruple, rsMaybe
     ,rsWrap, rsWrapMaybe, rsWrapEither, rsWrapEither',rsCondSeq
     ,rsChoice, rsAlt, rsTagSwitch, rsSwitch, rsCase, rsCaseConst
-    ,rsGetSet,rsCheckSet, rsLift, rsUnit, rsZero, rsWith
+    ,rsGetSet,rsCheckSet, rsLift, rsUnit, rsZero, rsWith, rsDefault
+    ,rsMaybeDefault
     )
 where
 
 ----------------------------------------
 -- STDLIB
 ----------------------------------------
-import Control.Monad (MonadPlus(..), msum, guard, liftM)
-import Control.Monad.Error (MonadError(..), Error(..), ErrorT)
+import Control.Monad (MonadPlus(..), guard, liftM)
+import Control.Monad.Error (MonadError(..), Error(..))
 import Control.Monad.Trans (MonadTrans, lift)
-import Control.Monad.Reader (MonadReader(..), ReaderT, runReaderT, ask, asks)
+import Control.Monad.Reader (MonadReader, ReaderT, runReaderT, ask, local, asks)
 
-import Data.Maybe (fromMaybe)
-import Data.List (find,elemIndex)
+import Data.List (find)
 
 -- ----------------------------------------------------------------------------
 --  SpecParser
@@ -135,6 +135,17 @@
 rsWrap :: Error e => (a -> b, b -> a) -> Spec e i o a -> Spec e i o b
 rsWrap (toB,toA) = rsWrapMaybe (error "BidiSpec: rsWrap") (return . toB, toA)
 
+rsMaybe :: Error e => Spec e i o a -> Spec e i o (Maybe a)
+rsMaybe rsA = mkSpec rsParseDef rsGenDef
+    where rsParseDef = liftM Just (rsParse rsA) `mplus` return Nothing
+          rsGenDef rout Nothing = rout
+          rsGenDef rout (Just a) = rsGen rsA rout a
+
+rsMaybeDefault :: Error e => a -> Spec e i o a -> Spec e i o a
+rsMaybeDefault defaultA rsA = mkSpec rsParseDef rsGenDef
+    where rsParseDef = rsParse rsA `mplus` return defaultA
+          rsGenDef = rsGen rsA
+
 rsWrapMaybe :: Error e =>
                String                        -- error message for Maybe case
             -> (a -> Maybe b, b -> a)        -- wrappers
@@ -183,7 +194,7 @@
          -> Spec e i o a
          -> (a -> Spec e i o b)
          -> Spec e i o b
-rsChoice pb = rsCondSeq pb undefined
+rsChoice pb = rsCondSeq pb (error "rsChoice: undefined")
 
 rsAlt :: Error e => (a -> Int) -> [Spec e i o a] -> Spec e i o a
 rsAlt getIdx alts = mkSpec rsParseDef rsGenDef
@@ -205,12 +216,12 @@
                a                               -- constant to match/generate
             -> (Spec e i o b -> Spec e i o b)  -- continuation
             -> SpecCase e i o a
-rsCaseConst a mkRs = rsCase (const a, const undefined) (mkRs (rsLift undef))
+rsCaseConst a mkRs = rsCase (const a, const undef) (mkRs (rsLift undef))
     where undef = error "rsCaseConst: this value should have been ignored"
 
 rsSwitch :: (Error e, Show a) => [SpecCase e i o a] -> Spec e i o a
-rsSwitch = rsTagSwitch (takeWhile take . dropWhile (=='(') . show)
-    where take x = x /= ' ' && x /= ','
+rsSwitch = rsTagSwitch (takeWhile isNotDelim . dropWhile (=='(') . show)
+    where isNotDelim x = x /= ' ' && x /= ','
 
 rsTagSwitch :: (Error e, Eq t) => (a -> t) -> [SpecCase e i o a] -> Spec e i o a
 rsTagSwitch tag cases = mkSpec rsParseDef rsGenDef
@@ -235,6 +246,10 @@
 rsCheckSet parser setfun rs = mkSpec rsParseDef rsGenDef
     where rsGenDef rout a = rsGen rs (setfun rout) a
           rsParseDef = parser >> rsParse rs
+
+rsDefault :: Error e => (e -> a) -> Spec e u i a -> Spec e u i a
+rsDefault onError (Spec gen parse) = Spec gen rsParseDef
+    where rsParseDef = catchError parse (return . onError)
 
 rsLift :: Error e => a -> Spec e i o a
 rsLift x = mkSpec (return x) const
