diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for plur
+
+## 0.1.0.0  -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2018, Joel Burget
+
+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 Joel Burget 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,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/plur.cabal b/plur.cabal
new file mode 100644
--- /dev/null
+++ b/plur.cabal
@@ -0,0 +1,21 @@
+name:                plur
+version:             0.1.0.0
+synopsis:            Plurality monad: Zero, one, or at least two.
+-- description:
+license:             BSD3
+license-file:        LICENSE
+author:              Joel Burget
+maintainer:          joelburget@gmail.com
+copyright:           (c) 2018 Joel Burget
+category:            Data
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.Plur
+  build-depends:
+    base >=4.11 && <4.12,
+    semigroups >= 0.18
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Data/Plur.hs b/src/Data/Plur.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Plur.hs
@@ -0,0 +1,61 @@
+{-# language LambdaCase #-}
+module Data.Plur (Plur(..), count) where
+
+import Data.Monoid
+import Data.Semigroup
+
+-- Plurality monad: Zero, one, or at least two.
+data Plur a
+  = Zero
+  | One a
+  | Two a a
+  deriving (Show, Eq, Ord)
+
+instance Functor Plur where
+  fmap f = \case
+    Zero      -> Zero
+    One a     -> One (f a)
+    Two a1 a2 -> Two (f a1) (f a2)
+
+instance Applicative Plur where
+  pure = One
+
+  (<*>) Zero _        = Zero
+  (<*>) _ Zero        = Zero
+  (<*>) (One f) x     = fmap f x
+  (<*>) (Two f1 f2) x = fmap f1 x <> fmap f2 x
+
+instance Monad Plur where
+  (>>=) x f = case x of
+    Zero      -> Zero
+    One x1    -> f x1
+    Two x1 x2 -> f x1 <> f x2
+
+instance Foldable Plur where
+  foldMap f = \case
+    Zero      -> mempty
+    One a     -> f a
+    Two a1 a2 -> f a1 <> f a2
+
+instance Traversable Plur where
+  traverse f = \case
+    Zero      -> pure Zero
+    One a     -> One <$> f a
+    Two a1 a2 -> Two <$> f a1 <*> f a2
+
+instance Semigroup (Plur a) where
+  r1      <> Zero    = r1
+  Zero    <> r2      = r2
+  One x   <> One y   = Two x y
+  One x   <> Two y _ = Two x y
+  Two x _ <> One y   = Two x y
+  Two x _ <> Two y _ = Two x y
+
+instance Monoid (Plur a) where
+  mempty = Zero
+
+count :: Plur a -> Int
+count = \case
+  Zero    -> 0
+  One _   -> 1
+  Two _ _ -> 2
