diff --git a/System/Console/CmdLib/ADTs.hs b/System/Console/CmdLib/ADTs.hs
--- a/System/Console/CmdLib/ADTs.hs
+++ b/System/Console/CmdLib/ADTs.hs
@@ -4,7 +4,7 @@
 import System.Console.CmdLib.Attribute
 import System.Console.CmdLib.Flag
 import System.Console.GetOpt
-import Control.Exception ( throw )
+import Control.Exception ( throw, evaluate )
 import Data.Data
 import Data.Generics.Aliases( extB )
 import Data.Maybe( fromMaybe )
@@ -29,15 +29,17 @@
 
   flag_attrkey (ADT x) = KeyC $ toConstr x
   flag_empty _ = []
+  flag_fold _ flags defs = flags' ++ [ f | f <- defs, toConstr f `notElem` map toConstr flags' ]
+    where flags' = foldr ($) [] flags
   flag_type (ADT flag) _ = optionType (gmapQ dataTypeOf flag) (gmapQ typeOf flag)
 
   flag_list = [ ADT $ fromConstr x | x <- dataTypeConstrs $ dataTypeOf (undefined :: adt) ]
-  flag_defaults attr = [ (setdef f:) | ADT f <- flag_list, length (gmapQ typeOf f) == 1,
-                                       enabled (attr $ ADT f) ]
+  flag_defaults attr initial = [ setdef f | ADT f <- flag_list, length (gmapQ typeOf f) == 1,
+                                            enabled (attr $ ADT f) ] ++ initial
     where setdef :: adt -> adt
           setdef f = fromConstrB (if required (attr $ ADT f)
-                                    then throw RequiredArgException
-                                    else defvalue $ attrs (ADT f) attr) (toConstr f)
+                                     then throw RequiredArgException
+                                     else defvalue $ attrs (ADT f) attr) (toConstr f)
 
   flag_attrs (ADT flag) = (attrFun $ attributes flag) (KeyC $ toConstr flag) %+
                           long (nameFromConstr $ toConstr flag) %+
@@ -45,6 +47,9 @@
 
   flag_set (ADT flag) v = (fromConstrB ((error "flag_set" `extB` v) ()) (toConstr flag) :)
   flag_parse (ADT flag) str = (fromConstrB (readFlag (undefined :: adt) str) (toConstr flag) :)
+  flag_eval (ADT flag) folded = case [ f | f <- folded, toConstr f == toConstr flag ] of
+    (x:_) -> gmapM evaluate x >> return ()
+    [] -> return ()
 
   flag_args (ADT flag) attr = case flag_type (ADT flag) attr of
     BooleanOption -> OptArg addoptional ""
diff --git a/System/Console/CmdLib/Command.hs b/System/Console/CmdLib/Command.hs
--- a/System/Console/CmdLib/Command.hs
+++ b/System/Console/CmdLib/Command.hs
@@ -96,8 +96,8 @@
   cmd :: cmd
   cmd = undefined
 
-  cmd_flag_empty :: cmd -> Folded flag
-  cmd_flag_empty _ = flag_empty (undefined :: flag)
+  cmd_flag_defaults :: cmd -> (flag -> [Attribute]) -> Folded flag
+  cmd_flag_defaults _ attrs = flag_defaults attrs (flag_empty (undefined :: flag))
 
 cmdoptions :: (Command cmd flag) => cmd -> Key -> [Attribute]
 cmdoptions = attrFun . options
@@ -133,9 +133,9 @@
 execute' cmd opts
   | "--help" `elem` opts && not (supercommand cmd) = printHelp cmd >> return Nothing
   | ("--help":_) <- opts = printHelp cmd >> return Nothing
-  | NoOptions <- optionStyle cmd = return $ Just (foldr ($) (cmd_flag_empty cmd) defaults, opts)
+  | NoOptions <- optionStyle cmd = return $ Just (defaults, opts)
   | otherwise = case errs' of
-                     [] -> do checkFlags (flags ++ defaults)
+                     [] -> do checkFlags (flag_fold' flags defaults)
                                 [f | f <- flag_list,
                                      enabled $ attrs f,
                                      not $ nonoption attrs f]
@@ -143,12 +143,12 @@
                               evaluate $ Just (flags', opts'filtered)
                      _ -> die (concat errs') >> return Nothing
   where getopts = optDescr attrs
+        checkFlags :: Folded f -> [f] -> IO ()
         checkFlags providedFlags allFlags =
-          forM_ allFlags $ \f -> checkFlag f fs
+          forM_ allFlags $ \f -> checkFlag f
          where
-            fs = foldr ($) (cmd_flag_empty cmd) providedFlags
-            checkFlag f fs =
-              (flag_eval f fs
+            checkFlag f =
+              (flag_eval f providedFlags
               `catch`
               \(_ :: RequiredArgException) ->
                 die $ "Missing required flag: " ++ flagDescr f)
@@ -157,7 +157,7 @@
 
         order = if supercommand cmd || (optionStyle cmd == NonPermuted) then RequireOrder else Permute
         (flags, opts', errs) = getOpt order getopts opts
-        flags' = foldr ($) (cmd_flag_empty cmd) (positions'' ++ extras ++ reverse flags ++ defaults)
+        flags' :: Folded f = flag_fold' (positions'' ++ extras ++ reverse flags) defaults
         extras :: [Folded f -> Folded f]
         extras = [ if extra (attrs f) then flag_set f opts'filtered else id
                  | f :: f <- flag_list, enabled $ attrs f ]
@@ -185,8 +185,8 @@
           (reverse $ sort $ map (\(_,s,_) -> s) positions)
         removemany = foldl remove
         remove l n = let (a, b) = splitAt n l in (a ++ drop 1 b)
-        defaults :: [Folded f -> Folded f]
-        defaults = flag_defaults attrs
+        flag_fold' = flag_fold (undefined :: f)
+        defaults = cmd_flag_defaults cmd attrs
         attrs :: f -> [Attribute]
         attrs = attrFun (cmdattrs cmd %% flag_attrs)
 
@@ -224,13 +224,6 @@
 
 commandGroup :: (Commands a) => String -> a -> [CommandWrap]
 commandGroup s l = [CommandGroup s (toCommands l)]
-
-#if !MIN_VERSION_base(4,3,0)
-instance Monad (Either e) where
-        return = Right
-        Left  l >>= _ = Left l
-        Right r >>= k = k r    
-#endif
 
 -- TODO: disambiguation, hidden commands (aliases)
 findCommand :: String -> [CommandWrap] -> [CommandWrap]
diff --git a/System/Console/CmdLib/Flag.hs b/System/Console/CmdLib/Flag.hs
--- a/System/Console/CmdLib/Flag.hs
+++ b/System/Console/CmdLib/Flag.hs
@@ -45,8 +45,8 @@
   flag_eval :: flag -> Folded flag -> IO ()
   flag_type :: flag -> [Attribute] -> OptionType
   flag_list :: [flag]
-  flag_defaults :: (flag -> [Attribute]) -> [Folded flag -> Folded flag]
-  flag_defaults _ = []
+  flag_defaults :: (flag -> [Attribute]) -> Folded flag -> Folded flag
+  flag_fold :: flag -> [Folded flag -> Folded flag] -> Folded flag -> Folded flag
   flag_empty :: flag -> Folded flag
 
 instance FlagType () where
@@ -214,6 +214,7 @@
           int = read :: String -> Int
           bool b | b `elem` ["yes", "true", "1", ""] = True
                  | b `elem` ["no", "false", "0"] = False
+                 | otherwise = error $ "Boolean expected in place of '" ++ b ++ "'"
           path = PathF
           strlist = (:[])
           list w str = map w (splitOn "," str)
diff --git a/System/Console/CmdLib/Record.hs b/System/Console/CmdLib/Record.hs
--- a/System/Console/CmdLib/Record.hs
+++ b/System/Console/CmdLib/Record.hs
@@ -60,7 +60,7 @@
           fixup BooleanOption | False <- invertible attr = SimpleOption
           fixup x = x
 
-  flag_defaults attr = map setfield flag_list
+  flag_defaults attr initial = foldr ($) initial $ map setfield flag_list
     where setdef :: forall a. (Data a) => Record rec -> a
           setdef flag = defvalue $ attrs flag attr
           setfield flag@(Record _ field) rec =
@@ -92,6 +92,7 @@
          setlist str v = setField field v (append (readFlag (undefined :: rec) str) (flag_value f v))
          setoptional str = set (fromMaybe "" str)
 
+  flag_fold _ flags defs = foldr ($) defs flags
   flag_empty _ = fromConstr $ head $ dataTypeConstrs $ dataTypeOf (undefined :: rec)
 
 -- | A bridge that allows multi-constructor record types to be used as a
@@ -166,10 +167,8 @@
           ctor = fromConstr $ rec_initial cmd :: cmd
 
   optionStyle cmd = rec_optionStyle (fromConstr $ rec_initial cmd :: cmd)
-
   supercommand cmd = rec_superCommand (fromConstr $ rec_initial cmd :: cmd)
-
-  cmd_flag_empty cmd = fromConstr $ rec_initial cmd
+  cmd_flag_defaults cmd attr = flag_defaults attr (fromConstr $ rec_initial cmd :: cmd)
 
 -- | Construct a command list (for "dispatch"/"helpCommands") from a
 -- multi-constructor record data type. See also "RecordCommand". Alternatively,
diff --git a/cmdlib.cabal b/cmdlib.cabal
--- a/cmdlib.cabal
+++ b/cmdlib.cabal
@@ -1,5 +1,5 @@
 name:        cmdlib
-version:     0.3.3
+version:     0.3.4
 synopsis:    a library for command line parsing & online help
 
 description: A commandline parsing library, based on getopt. Comes with a
@@ -45,6 +45,9 @@
   type:     darcs
   location: http://repos.mornfall.net/cmdlib
 
+flag mtl2
+  default:     True
+
 Library
   exposed-modules: System.Console.CmdLib
   other-modules: System.Console.CmdLib.Attribute
@@ -53,7 +56,11 @@
                  System.Console.CmdLib.ADTs
                  System.Console.CmdLib.Record
 
-  build-depends: base >= 4 && < 5, syb, mtl, split
+  build-depends: base >= 4 && < 5, syb, split
+  if flag(mtl2)
+      build-depends: mtl >= 2, transformers >= 0.2.2
+  else
+      build-depends: mtl < 2
 
 flag test
   default:     False
