diff --git a/Data/OpenUnion.hs b/Data/OpenUnion.hs
--- a/Data/OpenUnion.hs
+++ b/Data/OpenUnion.hs
@@ -4,6 +4,7 @@
     , (@>)
     , liftUnion
     , reUnion
+    , flattenUnion
     , restrict
     , typesExhausted
     ) where
diff --git a/Data/OpenUnion/Internal.hs b/Data/OpenUnion/Internal.hs
--- a/Data/OpenUnion/Internal.hs
+++ b/Data/OpenUnion/Internal.hs
@@ -18,13 +18,14 @@
     , (@!>)
     , liftUnion
     , reUnion
+    , flattenUnion
     , restrict
     , typesExhausted
     ) where
 
 import Control.Exception
 import Data.Dynamic
-import TypeFun.Data.List (SubList, Elem, Delete)
+import TypeFun.Data.List (SubList, Elem, Delete, (:++:))
 #if MIN_VERSION_base(4,10,0)
 import Data.Proxy
 import Data.Typeable
@@ -97,6 +98,12 @@
           sub = fromException some
       in fmap reUnion sub
 
+
+type family FlatElems a :: [*] where
+  FlatElems '[]              = '[]
+  FlatElems ((Union s) : ss) = s :++: FlatElems ss
+  FlatElems (x : s)          = x : FlatElems s
+
 -- general note: try to keep from re-constructing Unions if an existing one
 -- can just be type-coerced.
 
@@ -133,6 +140,11 @@
 reUnion :: (SubList s s') => Union s -> Union s'
 reUnion (Union d) = Union d
 {-# INLINE reUnion #-}
+
+-- | Flatten a @Union@.
+flattenUnion :: Union s -> Union (FlatElems s)
+flattenUnion (Union d) = Union d
+{-# INLINE flattenUnion #-}
 
 -- | Use this in places where all the @Union@ed options have been exhausted.
 typesExhausted :: Union '[] -> a
diff --git a/open-union.cabal b/open-union.cabal
--- a/open-union.cabal
+++ b/open-union.cabal
@@ -1,5 +1,5 @@
 name:               open-union
-version:            0.3.0.0
+version:            0.4.0.0
 synopsis:           Extensible, type-safe unions.
 category:           Data
 license:            MIT
@@ -98,4 +98,4 @@
 
 source-repository head
   type: git
-  location: https://github.com/RobotGymnast/open-union.git
+  location: https://github.com/bfops/open-union.git
