diff --git a/Boolean.cabal b/Boolean.cabal
new file mode 100644
--- /dev/null
+++ b/Boolean.cabal
@@ -0,0 +1,28 @@
+Name:                Boolean
+Version:             0.0.0
+Cabal-Version:       >= 1.2
+Synopsis:            Generalized boolean ops
+Category:            Data
+Description:
+  Some classes for generalized boolean operations.
+  .
+  Copyright 2009 Conal Elliott; BSD3 license.
+Author:              Conal Elliott
+Maintainer:          conal@conal.net
+Package-Url:         http://code.haskell.org/~conal/code/Boolean
+Copyright:           (c) 2009 by Conal Elliott
+License:             BSD3
+License-File:        COPYING
+Stability:           experimental
+build-type:          Simple
+
+Library
+  hs-Source-Dirs:      src
+  Extensions:
+  Build-Depends:       base<5
+  Exposed-Modules:
+                       Data.Boolean
+                       
+  ghc-options:         -Wall
+
+--  ghc-prof-options:    -prof -auto-all 
diff --git a/COPYING b/COPYING
new file mode 100644
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,25 @@
+Copyright (c) 2009 Conal Elliott
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. 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.
+3. The names of the authors may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,1 @@
+include ../cho-home-cabal-make.inc
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/src/Data/Boolean.hs b/src/Data/Boolean.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Boolean.hs
@@ -0,0 +1,163 @@
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies
+           , UndecidableInstances, ScopedTypeVariables
+  #-}
+{-# OPTIONS_GHC -Wall #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Data.Boolean
+-- Copyright   :  (c) Conal Elliott 2009
+-- License     :  BSD3
+-- 
+-- Maintainer  :  conal@conal.net
+-- Stability   :  experimental
+-- 
+-- Some classes for generalized boolean operations.
+-- 
+-- In this design, for if-then-else, equality and inequality tests, the
+-- boolean type depends functionally on the value type.  This dependency
+-- allows the boolean type to be inferred in a conditional expression.
+-- 
+-- I also tried using a unary type constructor class.  The class doesn't work
+-- for regular booleans, so generality is lost.  Also, we'd probably have
+-- to wire class constraints in like: @(==*) :: Eq a => f Bool -> f a -> f
+-- a -> f a@, which disallows situations needing additional constraints,
+-- e.g., Show.
+-- 
+----------------------------------------------------------------------
+
+module Data.Boolean
+  (
+    Boolean(..),IfB(..), boolean, cond, crop
+  , EqB(..), OrdB(..)
+  ) where
+
+import Data.Monoid (Monoid,mempty)
+import Control.Applicative (Applicative(..),liftA2,liftA3)
+
+
+{--------------------------------------------------------------------
+    Classes
+--------------------------------------------------------------------}
+
+infixr 3  &&*
+infixr 2  ||*
+
+-- | Generalized boolean class
+class Boolean b where
+  true, false  :: b
+  notB         :: b -> b
+  (&&*), (||*) :: b -> b -> b
+
+instance Boolean Bool where
+  true  = True
+  false = False
+  notB  = not
+  (&&*) = (&&)
+  (||*) = (||)
+
+-- | Types with conditionals
+class Boolean bool => IfB bool a | a -> bool where
+  ifB  :: bool -> a -> a -> a
+
+-- | Expression-lifted conditional with condition last
+boolean :: IfB bool a => a -> a -> bool -> a
+boolean t e bool = ifB bool t e
+
+-- | Point-wise conditional
+cond :: (Applicative f, IfB bool a) => f bool -> f a -> f a -> f a
+cond = liftA3 ifB
+
+-- | Crop a function, filling in 'mempty' where the test yeis false.
+crop :: (Applicative f, Monoid (f a), IfB bool a) => f bool -> f a -> f a
+crop r f = cond r f mempty
+
+
+infix  4  ==*, /=*
+
+-- | Types with equality.  Minimum definition: '(==*)'.
+class Boolean bool => EqB bool a | a -> bool where
+  (==*), (/=*) :: a -> a -> bool
+  u /=* v = notB (u ==* v)
+
+infix  4  <*, <=*, >=*, >*
+
+-- | Types with inequality.  Minimum definition: '(<*)'.
+class Boolean bool => OrdB bool a | a -> bool where
+  (<*), (<=*), (>*), (>=*) :: a -> a -> bool
+  u >*  v = v <* u
+  u >=* v = notB (u <* v)
+  u <=* v = v >=* u
+
+{--------------------------------------------------------------------
+    Some instances
+--------------------------------------------------------------------}
+
+ife :: Bool -> a -> a -> a
+ife c t e = if c then t else e
+
+-- I'd give the following instances:
+-- 
+--     instance IfB  Bool a where ifB = ife
+--     instance EqB  Bool a where { (==*) = (==) ; (/=*) = (/=) }
+--     instance OrdB Bool a where { (<*) = (<) ; (<=*) = (<=)}
+-- 
+-- Sadly, doing so would break the a->bool fundep, which is needed elsewhere
+-- for disambiguation.  So use the instances above as templates, filling
+-- in specific types for a.
+
+
+instance IfB  Bool Float where ifB = ife
+instance EqB  Bool Float where { (==*) = (==) ; (/=*) = (/=) }
+instance OrdB Bool Float where { (<*) = (<) ; (<=*) = (<=) }
+
+-- Similarly for other types.  
+
+
+instance (IfB bool p, IfB bool q) => IfB bool (p,q) where
+  ifB w (p,q) (p',q') = (ifB w p p', ifB w q q')
+
+instance (IfB bool p, IfB bool q, IfB bool r) => IfB bool (p,q,r) where
+  ifB w (p,q,r) (p',q',r') = (ifB w p p', ifB w q q', ifB w r r')
+
+instance (IfB bool p, IfB bool q, IfB bool r, IfB bool s) => IfB bool (p,q,r,s) where
+  ifB w (p,q,r,s) (p',q',r',s') =
+    (ifB w p p', ifB w q q', ifB w r r', ifB w s s')
+
+
+
+-- Standard pattern for applicative functors:
+
+instance Boolean bool => Boolean (z -> bool) where
+  true  = pure true
+  false = pure false
+  notB  = fmap notB
+  (&&*) = liftA2 (&&*)
+  (||*) = liftA2 (||*)
+
+instance IfB bool a => IfB (z -> bool) (z -> a) where
+  ifB = cond
+
+instance EqB  bool a => EqB  (z -> bool) (z -> a) where
+  { (==*) = liftA2 (==*) ; (/=*) = liftA2 (/=*) }
+instance OrdB bool a => OrdB (z -> bool) (z -> a) where
+  { (<*) = liftA2(<*) ; (<=*) = liftA2(<=*) }
+
+
+{-
+
+{--------------------------------------------------------------------
+    Tests
+--------------------------------------------------------------------}
+
+t1 :: String
+t1 = ifB True "foo" "bar"
+
+t2 :: Float -> Float
+t2 = ifB (< 0) negate id
+
+--     No instance for (IfB (a -> Bool) (a1 -> a1))
+--       arising from a use of `ifB'
+-- 
+-- t2 = ifB (< 0) negate id                -- abs
+
+-}
