diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,33 @@
+Copyright (c) 2010, 2011, 2012, wren ng thornton.
+ALL RIGHTS RESERVED.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of the copyright holders nor the names of
+      other contributors may be used to endorse or promote products
+      derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,7 @@
+#!/usr/bin/env runhaskell
+
+module Main (main) where
+import Distribution.Simple
+
+main :: IO ()
+main  = defaultMain
diff --git a/data-or.cabal b/data-or.cabal
new file mode 100644
--- /dev/null
+++ b/data-or.cabal
@@ -0,0 +1,50 @@
+----------------------------------------------------------------
+-- wren ng thornton <wren@community.haskell.org>    ~ 2011.07.12
+----------------------------------------------------------------
+
+Name:           data-or
+Version:        1.0.0
+Stability:      provisional
+Homepage:       http://code.haskell.org/~wren/
+Author:         wren ng thornton
+Maintainer:     wren@community.haskell.org
+Copyright:      Copyright (c) 2010--2011 wren ng thornton
+License:        BSD3
+License-File:   LICENSE
+
+Category:       Data
+Synopsis:       A data type for non-exclusive disjunction.
+Description:    A data type for non-exclusive disjunction.
+
+-- By and large Cabal >=1.2 is fine; but >= 1.6 gives tested-with:
+-- and source-repository:.
+Cabal-Version:  >= 1.6
+Build-Type:     Simple
+Tested-With:    GHC == 6.12.1, GHC == 6.12.3
+
+Source-Repository head
+    Type:     darcs
+    Location: http://community.haskell.org/~wren/data-or
+
+----------------------------------------------------------------
+Flag base4
+    Default:     True
+    Description: base-4.0 emits "Prelude deprecated" messages in
+                 order to get people to be explicit about which
+                 version of base they use.
+
+-- TODO: add flags for compiling against haskell98 or haskell2010
+-- instead of base?
+
+----------------------------------------------------------------
+Library
+    Hs-Source-Dirs:  src
+    Exposed-Modules: Data.Or
+    
+    if flag(base4)
+        Build-Depends: base >= 4 && < 5
+    else
+        Build-Depends: base < 4
+
+----------------------------------------------------------------
+----------------------------------------------------------- fin.
diff --git a/src/Data/Or.hs b/src/Data/Or.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Or.hs
@@ -0,0 +1,101 @@
+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}
+{-# LANGUAGE CPP #-}
+----------------------------------------------------------------
+--                                                    2011.06.03
+-- |
+-- Module      :  Data.Or
+-- Copyright   :  Copyright (c) 2010--2012 wren ng thornton
+-- License     :  BSD
+-- Maintainer  :  wren@community.haskell.org
+-- Stability   :  provisional
+-- Portability :  Haskell98 + CPP
+--
+-- A data type for non-exclusive disjunction. This is helpful for
+-- things like a generic merge function on sets\/maps which could
+-- be union, mutual difference, etc. based on which 'Or' value a
+-- function argument returns. Also useful for non-truncating zips
+-- (cf. 'zipOr') and other cases where you sometimes want an 'Either'
+-- and sometimes want a pair.
+----------------------------------------------------------------
+module Data.Or
+    ( Or(Fst,Both,Snd), elimOr, eitherOr
+    -- * Non-truncating zipping functions
+    , zipOr, zipOrWith, zipOrBy, zipOrWithBy
+    ) where
+
+#ifdef __GLASGOW_HASKELL__
+import GHC.Base (build)
+#endif
+----------------------------------------------------------------
+
+-- | A data type for non-exclusive disjunction.
+data Or a b = Fst a | Both a b | Snd b
+    deriving (Read, Show, Eq)
+
+
+-- | Functional eliminator for 'Or'.
+elimOr :: (a -> c) -> (a -> b -> c) -> (b -> c) -> Or a b -> c
+elimOr f _ _ (Fst  a)   = f a
+elimOr _ g _ (Both a b) = g a b
+elimOr _ _ h (Snd    b) = h   b
+{-# INLINE elimOr #-}
+
+
+-- | Convert an 'Either' into an 'Or'.
+eitherOr :: Either a b -> Or a b
+eitherOr (Left  a) = Fst a
+eitherOr (Right b) = Snd b
+{-# INLINE eitherOr #-}
+
+----------------------------------------------------------------
+
+-- | A variant of 'zip' which exhausts both lists, annotating which
+-- list the elements came from. It will return zero or more @Both@,
+-- followed by either zero or more @Fst@ or else zero or more @Snd@.
+--
+-- On GHC this is a \"good producer\" for list fusion.
+zipOr :: [a] -> [b] -> [Or a b]
+#ifdef __GLASGOW_HASKELL__
+zipOr xs ys = build (\f z -> zipOrWithBy id f z xs ys)
+#else
+zipOr = zipOrWithBy id (:) []
+#endif
+{-# INLINE zipOr #-}
+
+
+-- | A variant of 'zipOr' with a custom 'Or'-homomorphism.
+--
+-- On GHC this is a \"good producer\" for list fusion.
+zipOrWith :: (Or a b -> c) -> [a] -> [b] -> [c]
+#ifdef __GLASGOW_HASKELL__
+zipOrWith k xs ys = build (\f z -> zipOrWithBy k f z xs ys)
+#else
+zipOrWith k = zipOrWithBy k (:) []
+#endif
+{-# INLINE zipOrWith #-}
+
+
+-- | A variant of 'zipOr' with a custom list-homomorphism.
+zipOrBy :: (Or a b -> c -> c) -> c -> [a] -> [b] -> c
+zipOrBy = zipOrWithBy id
+{-# INLINE zipOrBy #-}
+
+
+-- | A variant of 'zipOr' with both a custom 'Or'-homomorphism and
+-- a custom list-homomorphism. This is no more powerful than
+-- 'zipOrBy', but it may be more convenient to separate the handling
+-- of 'Or' from the handling of @(:)@.
+zipOrWithBy
+    :: (Or a b -> c)    -- ^ 'Or' homomorphism
+    -> (c -> d -> d)    -- ^ list homomorphism, @(:)@ part
+    -> d                -- ^ list homomorphism, @[]@ part
+    -> [a] -> [b] -> d
+zipOrWithBy k f z = go
+    where
+    go []     []     = z
+    go []     (y:ys) = f (k (Snd    y)) (go [] ys)
+    go (x:xs) []     = f (k (Fst  x  )) (go xs [])
+    go (x:xs) (y:ys) = f (k (Both x y)) (go xs ys)
+
+----------------------------------------------------------------
+----------------------------------------------------------- fin.
